【问题标题】:How this lock block works? [closed]这个锁块是如何工作的? [关闭]
【发布时间】:2013-10-09 17:22:58
【问题描述】:

我看到一个头文件如下:

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

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

【问题讨论】:

  • 你有什么不明白的?

标签: c++ multithreading locking


【解决方案1】:

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

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

或者,使用更好的格式,

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

它通过Lock类的构造函数锁定了Mutex,而if()语句中的表达式由于Lockoperator bool() const的实现而总是计算为false,所以在else { } 部分被执行。

我想我还会提到,我认为这是一种......比必要的方式更复杂的方式来做到这一点。在作用域的开头声明一个新的Lock 并完全取消宏将是“同样容易”(并且可能更容易理解)。例如,Qt's QMutexLocker 就是这样使用的。

【讨论】:

    【解决方案2】:

    我们可以在这里做一点纸上的宏扩展:

    你的宏 =

    #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 来锁定互斥锁,returns 0 if succesful 并在互斥锁已被阻止时阻止。

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

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

    因为这总是返回false,所以我标记为BLOCK 1 的块永远不会被占用,而是调用你的临界区代码(BLOCK 2)。

    【讨论】:

    • 为什么它可以使用从 Mutex 类型到 Lock 类型的复制分配?
    • @injoy:因为Lock 有一个构造函数,它接受Mutex&amp;
    • BTW,你知道程序为什么要用Mutex&mutex_;在 Lock 类中?我的意思是 & 符号。
    • @injoy: Mutex&amp; 表示引用-Mutex
    • 所以复制分配意味着引用,而不是创建新副本,对吧?
    猜你喜欢
    • 2015-07-27
    • 2014-12-04
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 2021-11-14
    相关资源
    最近更新 更多