互斥体和lambda函数在c ++中

时间:2016-01-21 12:25:15

标签: c++ c++11 boost lambda mutex

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

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

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

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

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

2 个答案:

答案 0 :(得分:6)

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
});

它甚至支持通常的INVOKE语义:

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)...);
    }

如果标准采用这样的提案,您可以轻松地将其换掉。

答案 1 :(得分:2)

如果要在功能内部保护代码保护代码更小范围,则无需通过编写自己的保护功能来扩展互斥锁。您可以执行以下操作,使用花括号创建本地范围,当退出范围时,互斥锁将以异常安全的方式自动解锁。

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
} 

当然,这比你的自定义功能有缺点, 很难维持。有人可以在以后注册并注入更多代码而不知道他们在做什么。