Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Qt中两个线程之间的事件同步_C++_Qt_Thread Synchronization - Fatal编程技术网

C++ Qt中两个线程之间的事件同步

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)

我有两个线程,假设线程“A”和线程“B”。 线程“A”将其自定义QEvent发布到线程“B”,然后它应该等待线程“B”处理该事件

到目前为止我所做的:

我的活动类别:

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。