同步主线程和工作线程
Posted
技术标签:
【中文标题】同步主线程和工作线程【英文标题】:Synchronising main thread and worker thread 【发布时间】:2018-02-13 06:20:55 【问题描述】:在 QT 中,我正在从主(GUI)线程创建一个工作线程来执行某个操作,该操作访问两个线程共享的资源。在 GUI 中的某些操作上,主线程必须操作资源。我尝试使用QMutex
锁定该特定资源。这个资源一直被工作线程使用,如何通知主线程呢?
尝试使用QWaitCondition
,但它使应用程序崩溃。
还有其他选项可以通知和实现线程之间的同步吗? 附上代码sn-p。
void WorkerThread::IncrementCounter()
qDebug() << "In Worker Thread IncrementCounter function" << endl;
while(stop == false)
mutex.lock();
for(int i = 0; i < 100; i++)
for(int j = 0; j < 100; j++)
counter++;
qDebug() << counter;
mutex.unlock();
qDebug() << "In Worker Thread Aborting " << endl;
//Manipulating the counter value by main thread.
void WorkerThread::setCounter(int value)
waitCondition.wait(&mutex);
counter = value;
waitCondition.notify_one();
【问题讨论】:
一个由两个线程共享的资源 - 你真的需要这个吗,或者工作线程可以发出一个信号让主线程代表它访问资源?跨度> 看起来 waitCondition.wait 需要来自其他地方的通知才能真正释放它。不熟悉QWaitCondition,但如果它基于条件变量,通常等待会挂起,直到有人通知。我没有看到与 setCounter 中的等待相对应的通知。 【参考方案1】:您使用的等待条件完全错误。 我敦促您阅读互斥锁和条件,也许看看some examples。
wait() 将阻止执行,直到 notify_one() 或 notify_all() 在某处被调用。这当然不会发生在您的代码中。 您不能 wait() 一行上的条件,然后期望接下来的两行包含唯一的唤醒呼叫时会被调用。
你想要的是在一个线程中 wait() 并在另一个线程中 notify_XXX()。
【讨论】:
【参考方案2】:您可以在同一进程中使用共享内存。每个线程都可以在写入之前将其锁定,如下所示:
QSharedMemory *shared=new QSharedMemory("Test Shared Memory");
if(shared->create(1,QSharedMemory::ReadWrite))
shared->lock();
// Copy some data to it
char *to = (char*)shared->data();
const char *from = &dataBuffer;
memcpy(to, from, dataSize);
shared->unlock();
您还应该锁定它以供阅读。如果需要字符串,则读取字符串比编写字符串更容易,如果它们是零终止的。您需要将 .toLatin1() 转换为以零结尾的字符串,您可以获得字符串的大小。您可能会使用 shared->attach(); 获得多个线程可以读取的锁;但这更多是为了读取不同进程的共享内存..
您可以只使用它而不是静音。我认为,如果您尝试锁定它,而其他东西已经将其锁定,它将一直阻塞,直到其他进程将其解锁。
【讨论】:
以上是关于同步主线程和工作线程的主要内容,如果未能解决你的问题,请参考以下文章
laravel 队列 - 同步驱动程序如何工作?它是在单独的进程/线程还是主执行线程中执行?