[英]Is QThread::quit usabled from within the running thread
所以我有以下情況:
我有一個運行事件循環的QThread(即沒有自定義運行功能)。 要停止線程,我向該線程中的工作人員發送信號。 然后,該工作程序會進行清理等工作,並在某些時候完成並退出線程。
我現在面臨的問題是:如果我調用worker的stop方法,然后立即等待線程完成,它將永遠不會這樣做,因為沒有處理好worker的信號。 碼:
class Worker {
signals:
void done();
public slots:
void stop() {
//dummy code to illustrate what happens here:
QTimer::singleShot(3000, this, &Worker::done);
}
};
// in the main thread
auto thread = new QThread();
auto worker = new Worker();
worker->moveToThread(thread);
connect(worker, &Worker::done, thread, &QThread::quit); //implicitly a queued connection
// ...
QMetaObject::invokeMethod(worker, "stop", Qt::QueuedConnection);
thread->wait(); //blocks here forever, because the connect is queued
現在原因很明顯了-因為我在主線程上阻塞,所以永遠無法調用該插槽(因為已排隊連接),因此永遠不會調用quit。 但是,如果我直接從工作線程(或使用DirectConnection
)直接調用QThread::quit
(或QThread::exit
),那么就不再存在問題,因為不再需要主線程的eventloop來處理事件。
因此,這里的實際問題是:允許這樣做嗎? 我可以在實際線程中調用QThread::quit
嗎? 還是會造成比賽條件,僵局和其他類似問題。 文檔沒有將該方法標記為線程安全的-但是,由QThread管理的線程可能是一個例外。
如果您查看Qt源文件夾中的src/corelib/thread/qthread.cpp
文件,則可以看到quit()
的實現方式:
void QThread::quit()
{ exit(); }
....和QThread::exit()
絕對旨在從線程本身內部調用。 因此答案是肯定的,可以從QThread的線程中調用quit()
(盡管直接調用QThread::exit()
可能更常見)。
我可以在實際線程中調用
QThread::quit
嗎?
問題實際上是倒退!
由於此方法控制事件循環,並且事件循環最明確地在線程上運行,因此默認假設是它不是線程安全的方法,因此只能從線程內調用 ,因為它控制通過實例化的QEventLoop
實例QThread::run
。 該事件循環及其事件分發程序是QObject
並且絕對可以使它們的thread()
等於所討論的QThread
實例。
但這並不能使QThread
變得非常有用,因此QAbstractEventDispatcher::exit
以及QEventLoop::quit
和QThread::quit
確實是線程安全的方法-您可以從任何地方調用它們,包括從一個線程以外的線程調用事件循環所在的位置。 事件循環和線程的方法都采取了額外的預防措施來保護其狀態免受種族的影響,因此,幾句話之前的“因而”部分有點讓人費解。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.