C++ 中的互斥量和 lambda 函数
Mutexes and lambda functions in c++
在处理并发问题时我经常使用std::unique_lock<std::mutex>
和std::lock_guard<std::mutex>
,都没有问题。
我还扩展了 std::mutex
以便能够按如下方式使用它:
mutex.protect([](){
// my protected code here
}) ;
它锁定互斥量并在 lambda 调用前后释放它。
是否已经在 boost 或标准库中实现了类似的行为?
如果您只想在函数内保护代码较小范围,则不需要通过编写自己的保护功能。你可以像下面那样做,使用大括号创建一个本地范围,当范围退出时,互斥量将以异常安全的方式自动解锁。
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
}
当然这与您的自定义函数相比有缺点,
很难维护。稍后有人可以在不知道他们在做什么的情况下注入更多代码。
您可以像预期的那样使用它:
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)...);
}
如果标准曾经采用这样的提案,您可以轻松地将其换掉。
在处理并发问题时我经常使用std::unique_lock<std::mutex>
和std::lock_guard<std::mutex>
,都没有问题。
我还扩展了 std::mutex
以便能够按如下方式使用它:
mutex.protect([](){
// my protected code here
}) ;
它锁定互斥量并在 lambda 调用前后释放它。
是否已经在 boost 或标准库中实现了类似的行为?
如果您只想在函数内保护代码较小范围,则不需要通过编写自己的保护功能。你可以像下面那样做,使用大括号创建一个本地范围,当范围退出时,互斥量将以异常安全的方式自动解锁。
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
}
当然这与您的自定义函数相比有缺点, 很难维护。稍后有人可以在不知道他们在做什么的情况下注入更多代码。
您可以像预期的那样使用它:
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)...);
}
如果标准曾经采用这样的提案,您可以轻松地将其换掉。