Я хотел бы подтвердить то, что я считаю прямым аспектом рабочих потоков в Qt.
Предположим, я создаю QThread, целью которой является управление трудоемкой работой в соответствующем потоке. Кроме того, предположим, что я позволяю соответствующему циклу обработки событий этого потока вызывать start()
на QThread. Сама работа выполняется функцией-членом (слотом), которая сигнализируется QThread started()
сигнал.
То есть (копирование из https://stackoverflow.com/a/11039216/368896):
class Task : public QObject
{
Q_OBJECT
public:
Task();
~Task();
public slots:
void doWork()
{
//very time-consuming code is executed here before the next line is reached...
emit workFinished(); // Calls workFinished() signal (after a long time)
}
signals:
void workFinished();
};
// ... in the main thread:
QThread *thread = new QThread( );
Task *task = new Task();
task->moveToThread(thread);
connect( thread, SIGNAL(started()), task, SLOT(doWork()) );
connect( task, SIGNAL(workFinished()), thread, SLOT(quit()) );
//automatically delete thread and task object when work is done:
connect( thread, SIGNAL(finished()), task, SLOT(deleteLater()) );
connect( thread, SIGNAL(finished()), thread, SLOT(deleteLater()) );
thread->start();
Мой вопрос заключается в следующем. Я понимаю, что цикл обработки событий рабочего потока получит триггер от finished()
сигнал для того, чтобы вызвать deleteLater()
слот на task
пример. Кроме того, этот цикл событий будет запущен довольно скоро после doWork()
функция возвращает, и поэтому она будет готова и доступна для обработки триггера из finished()
сигнал, который был только что добавлен в очередь событий рабочего потока при вызове finished()
в конце doWork()
функция.
Я хотел бы подтвердить, что в течение всего времени трудоемкой операции, выполняемой внутри doWork()
(до finished()
испускается и до doWork()
функция завершается), что цикл обработки событий внутри рабочего потока блокированный на функции слота doWork()
и поэтому рабочий поток будет НЕ реагировать на любые слоты, срабатывающие на любых объектах, принадлежащих потоку цикла событий, в течение всего времени выполнения трудоемкого doWork()
функция. (И поэтому любые такие слоты будут выполняться только после doWork()
завершается, как только цикл событий рабочего потока снова становится активным, и перед триггером из finished()
сигнал обрабатывается.)
Я подозреваю, что это так, но я хочу подтвердить.
Спасибо!
Цикл событий рабочего потока будет заблокирован, т. Е. Вы не сможете обрабатывать какие-либо события (включая те, которые используются для «поставленных в очередь» соединений между сигналами и слотами, что вы и получаете, когда делаете соединения между слотами сигналов через потоки), если вы явно не инициируете вызов объекта цикла событий самостоятельно.
Однако в вашем рабочем потоке могут по-прежнему выполняться слоты, запускаемые сигналами, исходящими из рабочего потока, потому что это простые вызовы функций, и они не требуют запуска цикла обработки событий.
Других решений пока нет …