2015-09-29 3 views
0

У меня есть симуляция, работающая на std :: thread, которая имеет регулярные периоды спада, и в конце каждого периода QWidget::update() вызывается в моем обычном QGraphicsObject. Он работает большую часть времени, иногда вычисляя итерации 100 тыс. На сетке 1024^2, но иногда из точки QGraphicsView больше не обновляется. Я подозреваю, что проблема многопоточной связи.std :: thread security в Qt и QWidget update

Я читал, что Cocos2d-x, например, не может обрабатывать одновременные вызовы в своем API, исключая некоторые модификации свойств. Я не нашел информацию о безопасности потоков в Qt docs, некоторые говорят, что Qt Widgets не являются потокобезопасными. На самом деле QWidget :: update() является общедоступным слотом, поэтому попробую преобразовать все вызовы прямых функций в update(), чтобы испускать сигналы? Я хотел бы сделать мои потоки в чистом C++, каковы ограничения этого при работе с Qt?

(я открою новый вопрос конкретно о проблеме при использовании зОго :: нить, как это должна быть безопасным)

+0

Самая сложная задача для создания возможных дубликатов :( Этот вопрос был поставлен 4 года назад и имеет 5383 просмотров. Я все еще не мог найти его в google после запроса «qt thread-safety», хотя это имел «qt» и «thread-safety» в своих тегах ... Hmm – MatrixAndrew

ответ

1

В Qt очень важно, чтобы методы объектов GUI вызываются только в GUI (обычно основной).

Сигналы и слоты в Qt, однако, работают над границами потоков, если поток (слот) приемника работает в цикле событий (как видно из потока Qt). В этом потоке или потоке сигнального устройства нет другого требования. Если вы посылаете сигнал из другого потока, Qt автоматически помещает его в очередь событий потока получателя.

Это также можно сделать явным при настройке соединения сигнал/слот путем передачи правильного параметра типа соединения. См. explanation of connection types in Qt doc.

Таким образом, да, вы не можете надежно вызывать любые методы виджетов из других потоков и да, механизм сигналов/слотов является надлежащим средством обеспечения безопасности потоков при запуске действий графического интерфейса пользователя из рабочего потока.

+1

Да это работает как шарм: сигналы: void scheduleUpdate(); //////////////// общественности: пустота requestUpdate() {испускают scheduleUpdate();} //////////////// открытых слотов: недействительными executeUpdate() {обновление();} позвонив scheduleUpdate из std :: thread он дает выполнение потоку QObject таким образом. – MatrixAndrew