Qt 中两个线程之间的事件同步
Event synchronization between two threads in Qt
我有两个线程,假设线程"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":
QWaitCondition recvCondition;
IPCMessageEvent* pEvent = new IPCMessageEvent(&recvCondition);
QCoreApplication::postEvent(gpApp, pEvent);
QMutex mutex;
mutex.lock();
recvCondition.wait(&mutex, IPC_MESSAGE_WAIT_TIMEOUT);
我的线程"B":处理收到的事件并销毁它。~IPCMessageEvent 析构函数被调用,因此将为线程"A"中的recvCondition
启动wakeOne()
。
一切似乎都很好,这只是一件事!看起来有时~IPCMessageEvent的调用比预期的要早...
QCoreApplication::postEvent(gpApp, pEvent);
<---- pEvent is already destroyed here ---->
QMutex mutex;
mutex.lock();
所以我的recvCondition.wait(&mutex, IPC_MESSAGE_WAIT_TIMEOUT);
将被锁定并达到超时。
还有其他方法可以进行这种同步吗?或者也许有人有任何建议如何解决/克服这个问题?
嗯,你有一个经典的竞争条件。您的线程 A 可能会在发布事件后直接中断,然后线程 B 处理并销毁它。由于条件变量的通知只有在有人已经在等待时才有效,因此您会无限地错过通知,从而错过您的块。
因此,您需要在发布事件之前锁定互斥锁。但是,这要求线程 B 在处理事件时还需要锁定此互斥锁。否则,您无法阻止争用条件,因为线程 B 没有理由等待任何事情(或者知道它应该"等待"到线程 A 准备好等待条件变量)。
另类:
如果在两个线程(或位于两个线程中的对象)之间使用信号/插槽连接,则可以使用 Qt::BlockingQueuedConnection
。这可确保线程 A 在发出信号后阻塞,直到线程 B 中的事件循环处理它。
谢谢约翰内斯,我真的需要尝试使用您建议的信号/插槽替代方案。
我现在做的是:我创建了一个 QMutex 和布尔标志,用于线程"A"和线程"B"之间。
bool mIsProcessingMessage;
QMutex mIsProcessingMessageLock;
在线程"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.
};
在线程"B"中,当我的事件被处理时,我只是将我的"mIsProcessingMessage"标志设置为 true,如下所示:
{
QMutexLocker locker(&mIsProcessingMessageLock);
mIsProcessingMessage = false;
};
也许这不是最好的解决方案,但它现在有效;)
- 在cuda线程之间共享大量常量数据
- 类与私有变量的其他类之间的线程安全性
- 线程之间的布尔停止信号
- 试图创建一个多线程程序来查找0-100000000之间的总素数
- 线程之间的实时数据共享
- 通过插槽和信号在不同线程中的两个qt对象之间进行通信
- 线程之间的通信不起作用 - C++
- 简单使用 std::atomic 在两个线程之间共享数据
- 不同线程之间的互斥锁同步
- 运行线程和线程对象之间的关系
- 多个线程之间的获取-释放内存顺序
- 如何在两组线程之间正确来回传输控制权
- 对于同一任务,线程的等待时间在 0 到 30000 微秒之间系统地切换
- Qt:工作线程和 GUI 事件之间的关系
- 在 NUMA 节点之间散布 OpenMP 线程
- 由 std::shared_ptr 向量指向的数据之间的线程同步
- 通过为每个线程独占使用对象(不在线程之间共享)是保护该类的成员函数所必需的
- Libssh2:在"每个线程的通道"基础上在线程之间共享 ssh 会话是否安全?
- 如果两个线程调用同一个函数,但函数中的所有变量都是局部变量,我还需要担心线程之间共享数据吗?
- 填充和保存线程之间的共享缓冲区