我看到了一个头文件如下:
#include <pthread.h>
#define lock(x) if(Lock _lock_=x){}else
class Mutex{
public:
Mutex(){
pthread_mutex_init(&mutex_, 0);
};
~Mutex(){
pthread_mutex_destroy(&mutex_);
};
friend class Lock;
private:
pthread_mutex_t mutex_;
void Lock(){
pthread_mutex_lock(&mutex_);
};
void Unlock(){
pthread_mutex_unlock(&mutex_);
};
};
class Lock{
public:
Lock(Mutex& mutex):mutex_(mutex){mutex_.Lock();};
~Lock(){mutex_.Unlock();};
operator bool() const {
return false;
}
private:
Mutex& mutex_;
};
它定义了一个lock(x)
宏。以下是该宏的使用方式:
...
Mutex mtx;
lock(mtx) {
// critical section
}
...
那么,这个锁宏如何工作?为什么?
答案 0 :(得分:2)
因此,预处理器将就地扩展宏(基本上将其插入代码中)。所以你的例子就变成了:
...
Mutex mtx;
if(Lock _lock_=mtx){}else {
// critical section
}
...
或者,通过一些更好的格式化,
...
Mutex mtx;
if(Lock _lock_=mtx)
{
}
else
{
// critical section
}
...
它通过Lock
类的构造函数锁定Mutex,if()
语句中的表达式始终求值为false
,因为Lock
的实现operator bool() const
,因此执行else { }
部分中的代码。
我想我也会提到我认为这是一个......比做必要的方式更复杂。只是在范围的开头声明一个新的Lock
并且完全取消宏,这将是“同样简单”(并且可能更容易理解)。例如,这就是Qt's QMutexLocker的使用方式。
答案 1 :(得分:1)
我们可以在这里进行一些纸上宏观扩展:
你的宏=
#define lock(x) if(Lock _lock_=x){}else
使用它:
Mutex mtx;
lock(mtx) {
// critical section
}
在宏观替换后成为:
Mutex mtx;
if(Lock _lock_=mtx)
{
// BLOCK 1
}
else
{
// BLOCK 2
// critical section
}
因此,_lock_
正在从mtx
进行复制分配,pthread_mutex_lock
会尝试通过调用if
锁定互斥锁,returns 0
if succesful并阻止互斥锁已被阻止
Lock::operator bool()
块正在调用false
,它始终返回false
:
operator bool()const { 返回false; }
由于这始终会返回BLOCK 1
,因此我从未使用过的BLOCK 2
块,而是调用您的关键部分代码({{1}})。