【发布时间】:2020-12-06 11:03:55
【问题描述】:
我遇到了与QThread won't stop / does not process a signal 描述的完全相同的问题,但有一点不同。即使在我的while循环中使用QCoreApplication::processEvents(),我也无法让它工作。我关注了这个blog post,结果如下:
MediaController.cpp
void MediaController::buttonPlayClicked(bool checked)
{
if (checked)
{
m_loopThread = new QThread;
m_playPauseworker = new PlayPauseWorker;
m_playPauseworker->moveToThread(m_loopThread);
connect(m_playPauseworker, &PlayPauseWorker::dataReady, this, &MediaController::onDataReady);
connect(m_loopThread, &QThread::started, m_playPauseworker, &PlayPauseWorker::process);
connect(m_playPauseworker, &PlayPauseWorker::finished, m_loopThread, &QThread::quit); // <-- never works
connect(m_playPauseworker, &PlayPauseWorker::finished, m_playPauseworker, &PlayPauseWorker::deleteLater);
connect(m_loopThread, &QThread::finished, m_loopThread, &QThread::deleteLater);
m_loopThread->start();
}
else
{
m_loopThread->requestInterruption();
}
}
每次单击播放/暂停可检查按钮时都会调用上述插槽。在主线程上创建线程和worker。
PlayPauseWorker.cpp
void PlayPauseWorker::process()
{
while (!QThread::currentThread()->isInterruptionRequested())
{
// heavy computations
emit dataReady(std::tuple<QImage, QImage, QImage>>); // <-- works!
QCoreApplication::processEvents(); // <-- doesn't help with quit()
}
emit finished(); // <-- emits the signal but quit() not called
}
在进一步处理时,当我访问wait() 以查看我的线程是否已退出时,它永远不会返回。
除了从未调用过quit() 插槽之外,我注意到当线程运行时我的 GUI 变得非常不稳定。我有时可以/不能点击其他按钮或玩 UI。我浏览了很多 SO 帖子,但无法找到一种在需要时干净地退出线程的方法。不知道我哪里错了。
【问题讨论】:
-
明确地说,一旦单击播放按钮,您的 GUI 就没有响应?如果 GUI 无响应,您如何调用
requestInterruption? -
注释掉
connect(m_playPauseworker, &PlayPauseWorker::dataReady, this, &MediaController::onDataReady);是否有效? -
@m7913d 关于 GUI 无响应我编辑了我的问题。注释掉连接语句不起作用。
-
我自己无法复制这个;我整理了一个测试(没有 UI),其中有几个类的行为类似于您的
MediaController和PlayPauseWorker,并且看到线程退出。我不确定繁重的计算是否会破坏信号/插槽处理,但我不这么认为。请检查您是否在正确的线程上调用wait()。我在测试中没有使用wait(),而是使用connect(thread, &QObject::destroyed, [] { std::cout << "destroyed" << std::endl; });来查看线程何时被销毁;可以试试吗? -
我还在测试中注意到
QCoreApplication::processEvents()实际上并不需要事件传播到主线程。至于断断续续的问题,您可以通过将侧线程的线程优先级设置为较低来缓解一些问题?
标签: c++ multithreading qt qthread