在 start() 调用线程仍在运行时的 QThread 状态,但 after 已经不是



我有一个GUI线程,我可以在其中调用另一个MyQThread write(QString text)方法。
MyQthread包含QMutex mutexQList<QString> list。以下是write()run() MyQThread的方法:

void MyQThread::write(QString text)
{
     mutex.lock();
     list.append(text); //Point C
     mutex.unlock();
     start(); //Point D
}  
void MyQThread::run()
{
     mutex.lock();
     while(!list.isEmpty())
     {
         QString text = list.takeFirst();
         mutex.unlock();
         ...//do something
         mutex.lock(); //Point A
     }
     mutex.unlock(); //Point B
}  

例如,我们处于"A点"。在此之后,我们正在检查列表,它是空的,所以我们要去"B点"。此时调用write(),互斥锁仍处于锁定状态,因此 GUI 线程在"C 点"之前等待。
现在我们处于"B点",在此GUI线程解锁并调用start((("D点"(之后。
是否有可能在"D点"MyQThread仍在运行?
在这种情况下,调用start()什么都不做。并且list中新添加的项目将不会在run()中处理,直到下次调用write()
其他信息。就我而言,这里只是MyQThread的一个实例。

是的。尽管出现竞争条件的可能性很低,但我相信QThread仍然有可能发送信号等。在你打电话之前使用QThread::wait来确定start()

编辑:同意需要考虑QMutexLocker。该代码很快就会变得非常复杂,您无法确定您会记得在每个退出点解锁。

编辑2:也许QReadWriteLock在您的情况下可能更有趣?

@alexisdm感谢您的想法。这个解决方案怎么样:

class MyQThread:
    public: QThread
{
    ...
    QList<QString> list;
    QMutex mutex;
    QWaitCondition listNotEmpty;
}
void MyQThread::write(QString text)
{
     QMutexLocker locker(&mutex);
     list.append(text);
     listNotEmpty.wakeAll();
}  
void MyQThread::run()
{
     forever
     {
         mutex.lock();
         if(list.isEmpty())
             listNotEmpty.wait(&mutex);
         if(list.isEmpty())
         {
             mutex.unlock();
             continue;
         }
         QString text = list.takeFirst();
         mutex.unlock();
         ...//do something
     }
}  

那么wait()的第二个参数呢 - unsigned long time = ULONG_MAX.
在我看来,当长时间不调用该方法并且wait()会在ULONG_MAX后以run() false时,write()似乎不会出错。在这种情况下,我只需要再次等待...

并在文档中写道:

互斥锁将返回到相同的锁定状态。

这是否意味着,即使互斥锁在wait()wait()返回 false 之前未被锁定,wait()后也会始终锁定互斥锁?

QThread 有 'isRunning' 和 'isDone' 的方法。因此,您可以查询线程状态。当然,您的线程可能仍在"D点"运行。

但你真的应该停在这里做一些阅读。https://www.qt.io/blog/2010/06/17/youre-doing-it-wrong和http://woboq.com/blog/qthread-you-were-not-doing-so-wrong.html

最肯定的是关于QMutexLocker的Qt文档。

最新更新