qt - 如何使与 QTimer::timeout 关联的插槽可以被任何其他信号处理器(更高优先级)中断然后恢复?
问题描述
为了简化问题,假设我有一个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
会有帮助吗?)
解决方案
我不熟悉 IEEE802.11 暴露/隐藏节点问题,但是我认为您不能像您所描述的那样“中断”您的代码。
处理此问题的一种可能方法是在不同线程上运行 readyRead 和超时槽的代码,然后使用某种同步机制(想到 QMutex)来访问公共数据(并获取其状态)。
IE
添加某种 uniqueid 来识别 public_data 当前状态
timeout_slot 将获取锁,读取本地副本中的公共数据并释放锁,然后继续操作本地结构,最后在释放之前将再次获取锁并检查 uniqueid 是否已更改,如果是则提交您的工作,否则你必须重新开始。
readyRead_slot 将获取锁,更新 uniqueid 然后继续工作
推荐阅读
- c# - 一次创业下的不同种子
- git - 如何将隐藏文件合并到当前分支
- python - 为什么 a=[0] 的 list(x for x in a) 比 a=[] 快?
- function - haskell 风格的广义函数组合
- google-photos-api - 如何使用共享 URL 获取 Google 照片的 mediaItemId?
- php - php firebase推送通知ios:错误无效注册
- php - 在 mac osX 上升级到 php 7.4
- c++ - 使用 iptables 共享来自两个不同连接的 Internet 连接
- java - 在Spring配置中模拟命名bean而不使用allow-bean-definition-overriding?
- jquery - 如何避免在悬停时重新缩放?