在safmq系统中,对互斥量自己进行了进一步封装
CRITICAL_SECTION是不能够“锁定”资源的,它能够完成的功能,是同步不同线程的代码段。简单说,当一个线程执行了EnterCritialSection之后,cs里面的信息便被修改了,以指明哪一个线程占用了它。而此时,并没有任何资源被“锁定”。不管什么资源,其它线程都还是可以访问的(当然,执行的结果可能是错误的)。只不过,在这个线程尚未执行LeaveCriticalSection之前,其它线程碰到EnterCritialSection语句的话,就会处于等待状态,相当于线程被挂起了。 这种情况下,就起到了保护共享资源的作用。
虽然临界区同步速度很快,但却只能用来同步本进程内的线程,而不可用来同步多个进程中的线程。
MutexData定义:
struct MutexData {
MutexData() {
::InitializeCriticalSection(&csmtx); //初始化临界区
}
~MutexData() {
::DeleteCriticalSection(&csmtx); //删除临界区
}
void lock() {
::EnterCriticalSection(&csmtx); //进入临界区,上锁
}
void unlock() {
::LeaveCriticalSection(&csmtx); //离开临界区,解锁
}
CRITICAL_SECTION csmtx; //临界区变量
};
进行封装的Mutex类
class Mutex
{
public:
Mutex();
virtual ~Mutex();
void Lock();
void Unlock();
protected:
MutexData *data;
};
Mutex::Mutex()
{
data = new MutexData;
}
Mutex::~Mutex()
{
delete data;
}
void Mutex::Lock()
{
data->lock();
}
void Mutex::Unlock()
{
data->unlock();
}
class MutexLock
{
public:
MutexLock(Mutex* mtx) {
this->mtx = mtx;
this->mtx->Lock();
}
virtual ~MutexLock() {
this->mtx->Unlock();
}
protected:
Mutex *mtx;
};
使用实例:
qmtx是Mutex类型的数据,在访问que队列时,需要线程间互斥,所以把qmtx传递给了MutexLock,在MutexLock的构造函数中,可以看到,有lock操作,而在lock的有效期结束后,会自动调用析构函数,这是自调用Unlock操作,让其他等待qmtx的线程能够进入临界区,开始运行。
MutexLock lock(&qmtx);
que.push(msg);