我在使用qt同步多个线程时遇到问题(遗憾的是3.3.8)。因为启动一个线程是一项耗时的任务,所以我想启动一个(worker)线程一次,将其保存在run-method中并告知它有关新工作的信息。但是,当完成所有工作时,我还需要在调用线程中同步这些工作线程。
我知道QThread的重载不正确使用它,但在Qt 3.3.8中没有moveToThread-Method,所以我必须这样做。
worker-thread-class定义如下(简化)
class WorkerThread : public QThread
{
private:
QWaitCondition m_wcNewWork;
QMutex m_mutexStopped;
bool m_bStopped; /// Stop thread execution
void run()
{
m_mutexStopped.lock();
while(!m_bStopped)
{
m_mutexStopped.unlock();
m_wcNewWork.wait(); //wait for new work
msleep(1000); // do something
//>notify main thread that the work is done<
m_mutexStopped.lock();
}
m_mutexStopped.unlock();
}
public:
WorkerThread() : m_bStopped(false) {}
~WorkerThread()
{
m_mutexStopped.lock();
m_bStopped = true;
m_mutexStopped.unlock();
wait(); // Wait for thread
//Cleanup
}
void startProcessing()
{
m_wcNewWork.wakeOne(); /// Wakeup thread, since there is something to do
}
}
在另一个线程中创建了一堆工作线程。我们称之为 MainThread 。 现在我需要一些东西通知MainThread所有工作线程都已完成。我认为MainThread中的WaitConditions可以解决问题,每个WorkerThread都有一个问题。然后在MainThread中我写了类似
的内容QWaitCondition waitWorkDone[numWorker];
//Start working
for (int i = 0; i < numWorker; i++)
{
WorkerThread[i].setWaitCondition(waitWorkDone);
WorkerThread[i].startProcessing();
}
//Wait for all workers to finish their work
for (int i = 0; i < numWorker; i++)
{
waitWorkDone[i].wait();
}
在WorkerThread :: run-method中,我使用waitWorkDone.wakeOne()
通知MainThread工作已完成。不幸的是,这不起作用。当waitWorkDone在等待之前被唤醒时,MainThread将永远等待。
所以问题是:我如何同步线程,而不是离开他们的run-method?我认为在Qt 4中我可以使用线程池来实现这一点,但它们在Qt 3中不存在。
提前致谢。
答案 0 :(得分:0)
似乎您以错误的方式使用条件变量(QWaitCondition)。他们需要使用互斥锁才能正常工作,否则唤醒......呼叫可能会丢失,就像这里一样。 你可以修复它们,或者(更简单的方法)只使用信号量来等待工人;工作线程每次增加一次,主线程减少numWorker次数。
你可以在“PThread Primer”一书中找到关于条件变量的更好解释(非常好的多线程介绍,虽然有点过时)