此锁块的工作原理

How this lock block works?

本文关键字:工作      更新时间:2023-10-16

我看到一个头文件如下:

#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
}
...

那么,这个锁定宏是如何工作的呢?为什么呢?

因此,预处理器将就地扩展宏(实质上是将其插入代码中(。所以你的例子变成了:

...
Mutex mtx;
if(Lock _lock_=mtx){}else {
  // critical section
}
...

或者,使用一些更好的格式,

...
Mutex mtx;
if(Lock _lock_=mtx)
{
}
else
{
  // critical section
}
...

它通过 Lock 类的构造函数锁定互斥体,并且 if() 语句中的表达式总是因为Lockoperator bool() const的实现而计算结果为 false,因此执行else { }部分中的代码。

我想我还会提到,我会争辩说这是一个......比必要的方法更复杂。在范围开始时声明一个新Lock并完全取消宏"同样容易"(并且可能更容易理解(。例如,Qt的QMutexLocker就是这样使用的。

我们可以在这里做一些纸面宏扩展:

您的宏 =

#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 来锁定互斥锁,如果成功则返回0,如果互斥锁已经被阻止,则返回阻止。

if块调用Lock::operator bool(),它总是返回false

运算符 bool(( const { 返回假; }

由于这总是返回false,所以我标记BLOCK 1块永远不会被占用,而是调用您的关键部分代码(BLOCK 2(。