我有一个GUI线程,我调用另一个write(QString text)
的{{1}}方法
MyQThread
包含MyQthread
和QMutex mutex
。以下是QList<QString> list
的{{1}}和write()
方法:
run()
例如我们在'A点'。在此之后我们检查列表并且它是空的,所以我们将'指向B'。此时调用MyQThread
,互斥锁仍然被锁定,因此GUI线程在“C点”之前等待。
现在我们处于'B点',此GUI线程解锁后,调用start()('Point D')。
是否有可能,在'D点'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
}
什么都不做。在下次调用write()
之前,start()
中新添加的项目不会在list
中处理。
附加信息。在我的例子中,这里只有MyQThread的一个实例。
答案 0 :(得分:1)
是。虽然竞争条件的概率很低,但我相信QThread仍然有可能发送信号等。在致电start()
之前请先使用QThread::wait。
编辑:同意需要考虑QMutexLocker。那段代码会变得非常复杂,你不能确定你会记得每个出口点解锁。
Edit2:在你的情况下,QReadWriteLock可能会更有趣吗?
答案 1 :(得分:1)
@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
的第二个参数呢
似乎在我的情况下,当write()
方法长时间未被调用而wait()
将在false
之后run()
返回ULONG_MAX
时,它不会出错}。在这种情况下,我只需要再等一下......
在文档中写道:
互斥锁将返回到相同的锁定状态。
是否意味着,即使在wait()
或wait()
返回false之前未锁定互斥锁,wait()
之后互斥锁也会始终锁定?
答案 2 :(得分:0)
QThread的方法是'isRunning'和'isFinished'。所以你可以查询线程状态。当然,你的线程仍然可以在'D点'运行。
但是你真的应该停在这里并做一些阅读。 http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/ 和 http://woboq.com/blog/qthread-you-were-not-doing-so-wrong.html
大多数肯定是关于QMutexLocker的Qt文档。