【发布时间】:2014-04-04 21:11:38
【问题描述】:
使用mutex 锁定代码的关键区域的推荐方法是通过 RAII,即
mutex_type mutex;
{ // start of critical region
std::lock_guard<mutex_type> lock(mutex); // first statement in critical region
// ... do critical stuff, may throw an exception
} // end of critical region
这样当在临界区内抛出异常时,互斥锁仍然会被解锁(通过std::lock_guard 的析构函数)。但是,这样成员 mutex::lock() 和 mutex::unlock() 永远不会被用户代码显式调用。
Q如果有的话,mutex::lock() 的主要惯用显式用法是什么?
我在问,否则没有必要让 mutex::lock() 成为公共成员宣传不良代码(避免 std::lock_guard)。
编辑
由于std::lock_guard<> 和std::mutex 都定义在同一个标头中,std::mutex 可以轻松地与std::lock_guard<std::mutex 成为朋友,并使其lock() 和unlock() 方法受到保护:
class mutex // use only with lock_guard<mutex>
{
friend class lock_guard<mutex>; // support acquire-release semantic via RAII
friend class scoped_lock_guard<mutex>; // for supporting more complicated semantic,
// possibly remembering the mutex state.
// ...
protected:
void lock();
bool try_lock();
void unlock();
};
class raw_mutex // use if you absolutely must explicitly lock, try_lock, or unlock
: public mutex
{
public:
using mutex::lock;
using mutex::try_lock;
using mutex::unlock;
};
一个论点回答我的问题很简单,使用 mutex::lock() 的唯一异常安全方法是通过 RAII。因此,唯一合理的显式使用必须只涉及对lock(或try_lock)和unlock 的调用之间的noexcept 方法。然而,由于noexcept 只是暗示性的并且没有任何承诺,因此这样的使用是不安全的。 问正确吗?
【问题讨论】:
-
codereview.stackexchange.com/q/9431/2503
thread_start_lock -
@LightnessRacesinOrbit 你的代码看起来很吓人。
thread_start_lock.unlock()总是由调用thread_start_lock.lock()的同一线程调用,这一点并不明显,实际上看起来情况正好相反。 -
是的,这就是重点。
-
@LightnessRacesinOrbit ???所以关键是你的代码唤起了UB?您至少应该添加一个断言它不是。
-
UB跟它有什么关系?
标签: c++ multithreading c++11 locking mutex