我有一个 QThread 从我的 main 产生,它正在设备上进行同步读取。读取有 1000 毫秒超时。读取被包装在一个永久循环中,并且读取受到 QMutex 的保护。基本代码是:
线程 1 - 在设备上永久读取
for (;;){
readMutex.lock(); // Lock so that system cannot change device parameters in middle of read
read (&devicePtr, 1000);
readMutex.unlock; //Unlock so that thread 2 can grab lock if its waiting
}
我有另一种在主事件循环下运行的方法,可以为 devicePointer 设置一些参数。在读取设备时这样做是不安全的,因此它会尝试获取锁,然后设置参数,然后解锁互斥锁。这将允许线程 1 读取循环继续。基本代码是:
线程 2 - 设置设备参数
void setParm(){
readMutex.lock(); //Expects to take lock as soon as Thread 1 unlocks it
setParam (&devicePtr, PARAM);
readMutex.unlock(); //Unlock so thread 1 can resume its read forever loop
}
当每个线程获取锁时,我在代码中有一些 qDebug 转储线程 ID。我看到的是线程 2 调用锁并阻塞,而线程 1 拥有锁并正在读取。线程 1 完成读取并解锁 Mutex。线程 1 继续循环的下一次迭代,并再次获得锁。线程 2 在readMutex.lock ()调用上保持阻塞。在线程 2 最终被允许获取锁并继续之前,这将有 5 或 6 次。
我假设 QMutex 使用循环法将线程排队,但线程 1 似乎并非如此,它能够在下一次迭代中取回锁。如果我在解锁后将QThread::msleep(250)添加到线程 1 的循环末尾,我可以强制线程 2 获取锁。睡眠可以解决问题,线程 2 能够立即获取锁并设置设备参数。
我做错了什么,这是优先事项吗?知道如何在不使用 msleep 将线程 1 置于后台的情况下通过线程进行循环吗?