如何使插槽与QTimer :: timeout关联,可以被任何其他信号处理器(更高优先级)打断然后恢复?

时间:2019-05-08 08:45:51

标签: qt network-programming simulation 802.11

为简化问题,假设我有一个QTimer,它将每3000毫秒触发一次超时事件。

QTimer timer;

QObject::connect(&timer, &QTimer::timeout, [&](){
    // do sth(rely on a public data structure)
}); 

timer.start(3000);

连接到timeout事件的lambda内部的操作依赖于公共数据结构。

应用程序按住QUdpSocket,并将readyRead信号与插槽功能连接。

QUdpSocket socket;
socket.bind(45454, QUdpSocket::ReuseAddressHint);

QObject::connect(&socket, &QUdpSocket::readyRead, [&](){
    //manipulate the public data structure
}

如您所见,连接到readyRead信号的lambda操纵第一个lambda所依赖的公共数据结构。

所以我的问题是,我希望连接到readyRead信号的函数具有最高的“优先级”,也就是说,即使在Qt的事件循环中,现在也要处理timeout插槽,可以将其中断并立即启动readyRead插槽,然后完成操作,恢复timeout插槽功能。有什么办法吗?

(我的作业是模拟IEEE802.11暴露/隐藏节点问题,它要求我必须在发送数据包之前/期间不断地监听信道。)

(明确呼叫QCoreApplication::processEvent会有所帮助吗?)

1 个答案:

答案 0 :(得分:0)

我对IEEE802.11暴露/隐藏节点问题不熟悉,但是我认为您无法像所描述的那样“中断”您的代码。

一种可能的处理方式是在不同线程上运行readyRead和超时插槽的代码,然后使用某种同步机制(想到了QMutex)来访问公共数据(并获取其状态)

  1. 添加某种唯一标识以标识public_data的当前状态

  2. timeout_slot将获取一个锁,读取本地副本中的公共数据并释放该锁,然后继续操作本地结构,最后在释放之前将再次获取锁,并检查唯一标识是否已更改,如果因此,请提交您的工作,否则您将不得不重新开始。

  3. readyRead_slot将获得锁,更新唯一标识,然后继续工作