C++ Qt中两个线程之间的事件同步
我有两个线程,假设线程“A”和线程“B”。 线程“A”将其自定义QEvent发布到线程“B”,然后它应该等待线程“B”处理该事件 到目前为止我所做的: 我的活动类别:C++ Qt中两个线程之间的事件同步,c++,qt,thread-synchronization,C++,Qt,Thread Synchronization,我有两个线程,假设线程“A”和线程“B”。 线程“A”将其自定义QEvent发布到线程“B”,然后它应该等待线程“B”处理该事件 到目前为止我所做的: 我的活动类别: class IPCMessageEvent : public QEvent { public: IPCMessageEvent(QWaitCondition* pConditions) : QEvent(IPC_MESSAGE_RECEIVED)
class IPCMessageEvent : public QEvent
{
public:
IPCMessageEvent(QWaitCondition* pConditions) : QEvent(IPC_MESSAGE_RECEIVED)
, mpWaitCondition(pConditions)
{ };
~IPCMessageEvent()
{
mpWaitCondition->wakeOne();
};
private:
QWaitCondition* mpWaitCondition;
};
我的线程“A”:
我的线程“B”:处理接收到的事件并销毁它~IPCMessageEvent析构函数被调用,因此线程“A”中的recvCondition将启动wakeOne()
一切似乎都很好,只有一件事!
看起来有时~IPCMessageEvent调用的时间比预期的要早
QCoreApplication::postEvent(gpApp, pEvent);
<---- pEvent is already destroyed here ---->
QMutex mutex;
mutex.lock();
QCoreApplication::postEvent(gpApp、pEvent);
QMutex互斥;
mutex.lock();
所以我的recvCondition.wait(&mutex,IPC\u MESSAGE\u wait\u TIMEOUT)代码>将被锁定并达到超时
还有其他方法可以实现这种同步吗?
或者有人对如何解决/克服这个问题有什么建议?好吧,你有一个经典的竞赛条件。发布事件后,线程A可能会直接中断,线程B会处理并销毁事件。由于条件变量的通知只有在有人已经在等待时才起作用,因此您会无限地错过通知,从而导致阻塞
因此,您需要在发布事件之前锁定互斥锁。但是,这要求线程B在处理事件时也需要锁定此互斥锁。否则,您无法阻止争用条件,因为线程B没有理由等待任何事情(或者知道它应该“等待”直到线程A准备好等待条件变量)
备选方案:
如果在两个线程(或两个线程中的对象)之间使用信号/插槽连接,则可以使用Qt::BlockingQueuedConnection
。这将确保线程A在发出信号后阻塞,直到线程B中的事件循环对其进行处理 谢谢约翰,
我真的需要尝试使用您建议的信号/插槽替代方案
我现在所做的是:
我已经创建了一个QMutex和boolean标志,用于线程“a”和线程“B”之间
在线程“A”中,我发布的事件如下:
IPCMessageEvent* pEvent = new IPCMessageEvent();
{ // Inform everyone that we will be processing our message.
QMutexLocker locker(&mIsProcessingMessageLock);
mIsProcessingMessage = true;
};
QCoreApplication::postEvent(gpApp, pEvent, Qt::HighEventPriority);
forever // Loop until event will get processed.
{
QMutexLocker locker(&mIsProcessingMessageLock);
if (mIsProcessingMessage == false)
break;
::Sleep(2); // Don't load up the CPU.
};
{
QMutexLocker locker(&mIsProcessingMessageLock);
mIsProcessingMessage = false;
};
在线程“B”中,当处理我的事件时,我只需将我的“MissProcessingMessage”标志设置为true,如下所示:
IPCMessageEvent* pEvent = new IPCMessageEvent();
{ // Inform everyone that we will be processing our message.
QMutexLocker locker(&mIsProcessingMessageLock);
mIsProcessingMessage = true;
};
QCoreApplication::postEvent(gpApp, pEvent, Qt::HighEventPriority);
forever // Loop until event will get processed.
{
QMutexLocker locker(&mIsProcessingMessageLock);
if (mIsProcessingMessage == false)
break;
::Sleep(2); // Don't load up the CPU.
};
{
QMutexLocker locker(&mIsProcessingMessageLock);
mIsProcessingMessage = false;
};
也许这不是最好的解决方案,但目前它仍然有效;) 顺便说一句,你真的应该回到你以前的问题,接受最好的答案。否则,人们将不再为你的问题操心,你将来也不会得到任何答案。谢谢Johannes S.的提示;)你仍然可以用你的方法。我建议您阅读一下线程同步和条件变量的工作原理。基本上,您需要“共享”一个互斥体和一个条件变量。在发布事件之前锁定互斥锁,并等待CV(释放互斥锁)。在事件处理线程中获取互斥体,处理事件,释放互斥体,然后通知CV。