QPointer в многопоточных программах - PullRequest
3 голосов
/ 28 сентября 2011

Согласно http://doc.qt.io/qt-5/qpointer.html, QPointer очень полезен.Но я обнаружил, что это может быть неэффективно в следующем контексте:

Если я хочу показать ярлык три раза или сделать что-то еще, я должен использовать

if(label) label->show1(); if(label) label->show2(); if(label) label->show3();

вместо if(label) { label->show1();label->show2();label->show3(); }

только потому, что метка может быть уничтожена в другом потоке после label->show1(); или label->show2();.

Есть лиПрекрасный способ, кроме трех ifs, получить ту же функциональность?

Другой вопрос, когда метка уничтожается после if (label), if(label) label->show1(); все еще не так?

У меня нетопыт работы в многопоточных программах.Любая помощь приветствуется.;)

Ответы [ 2 ]

6 голосов
/ 29 сентября 2011

Я думаю, что единственный безопасный способ сделать это - убедиться, что вы обращаетесь к своим QWidgets только из основного потока / потока GUI (то есть потока, в котором выполняется цикл обработки событий Qt, внутри QApplication :: exec ()).

Если у вас есть код, который выполняется в другом потоке, и этот код хочет, чтобы QLabels отображался / скрывался / что угодно, тогда этот код должен создать объект QEvent (или его подкласс) и вызвать qApp-> postEvent () для отправки этого объекта в основной поток.Затем, когда цикл событий Qt выбирает и обрабатывает это QEvent в основном потоке, это точка, в которой ваш код может безопасно выполнять действия с QLabels.

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

0 голосов
/ 29 сентября 2011

Ни один из ваших подходов не является поточно-ориентированным. Вполне возможно, что ваш первый поток выполнит оператор if, затем другой поток удалит вашу метку, и тогда вы попадете внутрь оператора if и произойдет сбой.

Qt предоставляет несколько конструкций синхронизации потоков, вы, вероятно, захотите начать с QMutex и узнать больше о безопасности потоков, прежде чем продолжить работу над этой программой.

Использование мьютекса сделает вашу функцию похожей на это:

mutex.lock();
label1->show();
label2->show();
label3->show();
mutex.unlock()

Пока ваш другой поток использует блокировку того же объекта мьютекса, он не сможет удалять ваши метки, пока вы их показываете.

...