在处理并发问题时,我经常使用std::unique_lock<std::mutex>
和std::lock_guard<std::mutex>
,两者都没问题。
我还扩展了std::mutex
以便能够使用它如下:
mutex.protect([](){
// my protected code here
}) ;
它锁定互斥锁并在lambda调用周围释放它。
在boost或标准库中是否已经实现了类似的行为?
答案 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
}
当然,这比你的自定义功能有缺点, 很难维持。有人可以在以后注册并注入更多代码而不知道他们在做什么。