繁体   English   中英

QThread :: quit是否可以从正在运行的线程中使用

[英]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::quitQThread::quit确实是线程安全的方法-您可以从任何地方调用它们,包括从一个线程以外的线程调用事件循环所在的位置。 事件循环和线程的方法都采取了额外的预防措施来保护其状态免受种族的影响,因此,几句话之前的“因而”部分有点让人费解。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM