仔细研究旧项目和大型项目的遗留代码,我发现使用了一些奇怪的方法来创建线程安全队列,如下所示:
template < typename _Msg>
class WaitQue: public QWaitCondition
{
public:
typedef _Msg DataType;
void wakeOne(const DataType& msg)
{
QMutexLocker lock_(&mx);
que.push(msg);
QWaitCondition::wakeOne();
}
void wait(DataType& msg)
{
/// wait if empty.
{
QMutex wx; // WHAT?
QMutexLocker cvlock_(&wx);
if (que.empty())
QWaitCondition::wait(&wx);
}
{
QMutexLocker _wlock(&mx);
msg = que.front();
que.pop();
}
}
unsigned long size() {
QMutexLocker lock_(&mx);
return que.size();
}
private:
std::queue<DataType> que;
QMutex mx;
};
wakeOne
从线程中用作“发布”功能”,并wait
从其他线程调用并无限期地等待,直到消息出现在队列中。在某些情况下,线程之间的角色在不同阶段反转并使用单独的队列。
这甚至是QMutex
通过创建本地方法来使用 a 的合法方式吗?我有点理解为什么有人可以在读取大小时这样做来避免死锁,que
但它是如何工作的?有没有更简单、更惯用的方法来实现这种行为?