c++:互斥、守卫和函数调用

标签 c++ concurrency scope locking mutex

我在想。当我使用一个std::mutex _lock 并想依赖守卫来释放它时,我可以这样使用吗?

class MyClass{
private:
    mutable std::mutex _lock;
    void subroutine(){/*...*/}
public:
    void foo(){
        std::lock(_lock);std::lock_guard<std::mutex> g(_lock, std::adopt_lock);
        subroutine();
        //require I still have the lock here
        //...
        return; //g goes out of scope ==> _lock is released
    }
};

或者对 subroutine 的调用是否已经导致锁被释放?如果事实证明是后者,我有什么选择?

更新

这个案例呢?

class MyClass{
private:
    mutable std::mutex _lock;
public:
    void subroutine(){ //can be called on its own
        std::lock(_lock);std::lock_guard<std::mutex> g(_lock, std::adopt_lock);
        /*...*/
    }
    void foo(){
        std::lock(_lock);std::lock_guard<std::mutex> g(_lock, std::adopt_lock);
        subroutine();
        //require I still have the lock here
        //...
        return; //g goes out of scope ==> _lock is released
    }
};

最佳答案

调用子程序不会导致锁被释放。 当 std::lock_guard 对象超出范围时(正如您在评论中提到的那样),线程对 _lock 的锁定被释放。

void foo(){
    std::lock_guard<std::mutex> lg{_lock}; // lock the mutex
    subroutine(); // lock is held here during this call
    // so subroutine must not attempt to lock the mutex _lock!
    return; // lg goes out of scope => its destructor is called which releases the lock on _lock
}

要回答您的第二个问题,当 foo 获取 _lock 上的锁然后调用子例程,子例程再次尝试锁定 _lock 时,您遇到了问题。线程无法在它已经持有锁的互斥锁上获取锁。我会重新考虑你的类(class)设计。如果你绝对必须有这种设计,你可以做类似的事情

void subroutine(bool called_from_foo = false)
{
    if(!called_from_foo)
        std::lock_guard<std::mutex> lg{_lock};
    /* ... */
}

void foo()
{
    std::lock_guard<std::mutex> lg{_lock};
    subroutine(true);
    /* ... */
    return;
}

尽管我不推荐这样做,因为它很容易以错误的方式使用子例程,导致程序出现未定义的行为。

如果您发现自己必须在函数之间传递锁的所有者,我会看一下 std::unique_lock,因为这种类型是可移动的。

关于c++:互斥、守卫和函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33722020/

相关文章:

c++ - 在 C++ 中多次初始化数组时会发生什么?

c++ - xcode 中的子文件夹。链接

c++ - 数的倒数,C++

java - Java 中的引用计数

loops - 为什么无限循环不递增整数?

使用 join() 的 Java 多线程程序在计算相邻数字之和时给出了错误的结果

java - 如何在 do while 循环中初始化变量而不传递值直到循环关闭?

javascript - 将范围传递给回调函数/绑定(bind)

javascript - Ng-click 不起作用

c++ - 类型 'int&' 的引用初始化无效,传递参数 1 时出错