C++ 中的互斥函数和 lambda 函数

Mutexes and lambda functions in c++

本文关键字:函数 lambda C++      更新时间:2023-10-16

在处理并发问题时,我经常使用std::unique_lock<std::mutex>std::lock_guard<std::mutex>,两者都没有问题。

我还扩展了std::mutex以便能够按如下方式使用它:

mutex.protect([](){
    // my protected code here
}) ;

它锁定互斥锁并在 lambda 调用周围释放它。

这种类似的行为是否已经在 boost 或标准库中实现?

Boost Thread 有这个: http://www.boost.org/doc/libs/1_58_0/doc/html/thread/synchronization.html#thread.synchronization.with_lock_guard

您可以像预期的那样使用它:

std::mutex mx;
boost::with_lock_guard(mx, []{
    // protected stuff
});

它甚至支持通常的调用语义:

int foo(int,double) { return 42; }
// ...
int answer = boost::with_lock_guard(mx, foo, 3, 3.14);

仅标准库手动实施

您可以轻松地自己添加这样的东西:

template <typename M, typename F, typename... Args> 
    auto my_with_lock_guard(M& mx, F&& f, Args&&... args) {
        std::lock_guard<M> lk(mx);
        return std::forward<F>(f)(std::forward<Args>(args)...);
    }

如果标准采用了这样的建议,你可以很容易地把它换掉。

如果你只想函数内保护较小范围内的代码,则不需要通过编写自己的保护函数来扩展互斥锁。您可以执行以下操作,使用大括号创建本地作用域,当作用域退出时,互斥锁将以异常安全的方式自动解锁。

double process_func() { 
// do some stuff
    { //start a new scope block
      std::lock_guard<my_mutex> g; // mutex is locked here.
      []() { } // your lambda that needs to be protected
    } // Mutex is released here.
// do more stuff
} 

当然,这比您的自定义函数有缺点,很难维护。有人可以稍后来注入更多代码,而不知道他们在做什么。