这个锁定块如何工作?

时间:2013-10-09 17:22:59

标签: c++ multithreading locking

我看到了一个头文件如下:

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

那么,这个锁宏如何工作?为什么?

2 个答案:

答案 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}})。