用惯了Boost的mutex和Condition,突然发现QT的互斥锁与信号量跟Boost的这么神似! 所以今儿将QT的互斥与信号量做个小抄,方便后续查看!
同时,记录一下先前对condition的使用一直比较模糊的地方顺便也做个笔记!
// QThreadAndMutexLocker.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <QtCore\qthread>
#include <QtCore\qmutex>
#include <QtCore\qwaitcondition>
QMutex g_mutex;
QWaitCondition g_cond;
class CA : public QThread
{
public:
CA(){ start(); }
~CA(){ wait(); }
private:
void run()
{
for (size_t i = 0; i < 10; i++)
{
QThread::msleep(100);
QMutexLocker l(&g_mutex);
std::cout << "CA locked and call wakeAll() " << i << std::endl;
g_cond.wakeAll();
/*以下注释部分证明g_cond.wakeAll()只是发出信号,但没有解锁,wakeAll下面代码部分仍是CA的锁范围之内
注:因此g_cond.wakeAll调用之后,CB线程虽拿到信号但直到CA线程释放锁才行。
结论:情况1:g_cond.wakeAll()在CA的锁范围之内, CA线程调用wakeAll(),CB拿到信号并准备解锁,CA释放锁,CB拿到锁
情况2:g_cond.wakeAll()在CA的锁范围之外, CA线程调用wakeAll(),CB拿到信号并准备解锁,CA与CB产生抢锁
因此:g_cond.wakeAll()即可在锁范围内出现也可出现在锁范围外,但是,场景1的明显效率高于场景2。如果在CA
的锁范围外调用一次sleep,能更能有效的确保CB能第1时间拿到锁。
*/
//for (size_t i = 0; i < 10; i++)
//{
// std::cout << " CA : " << i << std::endl;
// QThread::msleep(1000);
//}
}
QThread::msleep(1); //等待1ms,让CA线程挂机,确保CB线程能即时拿到锁.
}
};
class CB : public QThread
{
public:
CB(){ start(); }
~CB(){ wait(); }
private:
void run()
{
for (size_t i = 0; i < 10; i++)
{
QMutexLocker l(&g_mutex);
std::cout << " CB locked, and waitting condition!" << std::endl;
g_cond.wait(&g_mutex); // 1: wait时,将调用g_mutex.unlock(); 2:等到信号时,将调用g_mutex.lock();
for (size_t i = 0; i < 10; i++)
{
std::cout << " CB : " << i << std::endl;
QThread::msleep(1000);
}
}
}
};
int _tmain(int argc, _TCHAR* argv[])
{
{
CB cb;
QThread::msleep(2000);
CA ca;
}
getchar();
return 0;
}