【发布时间】:2013-11-20 05:27:25
【问题描述】:
我偶然发现了这个问题,就像其他人一样: QThread won't stop / does not process a signal QThread - Using a slot quit() to exit the thread
问题是我想启动一个工作线程,做一些工作(包括在我的代码中向其他线程发送信号,并异步接收信号)然后退出。但我希望这个线程与启动它的代码同步。换句话说,我希望在创建工作线程的代码中停止执行,直到工作线程完成其工作。
但这似乎在 Qt 中是不可能的。原因是工作线程的 QThread.quit() 槽不能从线程本身发出信号。侦听此插槽信号的事件循环应驻留在创建工作线程的同一线程中。这意味着创建线程不应该被阻塞,否则工作线程永远不会停止。
这让我想到了我的问题,那 QThread.wait() 有什么意义呢?我认为这个函数应该只是卡在程序的末尾以确保所有线程都已退出,但它实际上不能用于同步线程,至少它不能用于将工作线程与创建的线程同步它。因为如果从创建线程调用 QThread.wait(),它会阻塞它的事件循环,这将阻塞工作线程的接口,这将阻止它退出。
我错过了什么吗?
我想我需要添加一个代码sn-p:
for (auto i = myVector.begin(); i < myVector.end(); ++i)
{
// 5-line best practice creation for the thread
QThread* workerThread = new QThread;
MyWorkerObject* workerObject = new MyWorkerObject(0);
workerObject->moveToThread(workerThread);
QObject::connect(workerThread, SIGNAL(started()), workerObject, SLOT(init()));
QObject::connect(workerThread, SIGNAL(finished()), workerObject, SLOT(deleteLater()));
// Stop mechanism
QObject::connect(workerObject, SIGNAL(finished()), workerThread, SLOT(quit()));
// Start mechanism
wokerThread->start();
// Invoking the work
QMetaObject::invokeMethod(workerObject, "StartYourJob", Qt::QueuedConnection, Q_ARG(SomeType, *i));
// Synchronization
workerThread->wait();
delete wokerThread;
}
【问题讨论】:
-
I want the execution in the code which creates the worker thread to be halted until the worker thread is done its job.看来你根本不需要线程。 -
Alex,正如我所提到的,worker 的工作“涉及在我的代码中向其他线程发送信号,并异步接收信号”。如果我根本不创建线程,就不会有事件循环来监听信号......
-
QThread::wait需要进行清理。它一直等到超时或线程完成。你不应该删除正在运行的线程的对象,因为它会导致意想不到的错误,所以在删除之前你应该调用wait(someInterval) -
这就是我正在做的事情 Marek。请看我添加的代码 sn-p...
标签: c++ multithreading qt