我的问题很简单。在 C++11 中,我们有 std::mutex
和 std::lock_guard
和 std::unique_lock
。
通常使用这些类的方法是通过任何锁来锁定std::mutex
。这可以防止由于异常抛出而导致的互斥锁泄漏:
{
std::lock_guard<std::mutex> l(some_mutex);
//Cannot leak mutex.
}
为什么 std::mutex::lock
和 std::mutex::unlock
是公开的?这要求不正确的用法:
{
some_mutex.lock();
//Mutex leaked due to exception.
some_mutex.unlock();
}
让 std::lock_guard
和 std::unique_lock
成为 std::mutex
的 friend 并让 std::mutex
锁定操作私有(private)?这将防止不安全的使用。
对于这种设计,我能猜到的唯一原因是,如果我有自己的锁,它就不能与 std::mutex
一起使用,因为我无法制作自己的锁锁定 std::mutex
的友元。这是公开这些成员函数的主要原因吗?
最佳答案
此设计决策的基本原理记录在 N2406 中:
Unlike boost, the mutexes have public member functions for lock(), unlock(), etc. This is necessary to support one of the primary goals: User defined mutexes can be used with standard defined locks. If there were no interface for the user defined mutex to implement, there would be no way for a standard defined lock to communicate with the user defined mutex.
在撰写本文时,boost::mutex 只能通过 boost::scoped_lock 锁定和解锁。
所以你现在可以写my::mutex
,只要你供应成员(member)lock()
和 unlock()
, 你的 my::mutex
和std::mutex
一样是一等公民.您的客户可以使用 std::unique_lock<my::mutex>
就像他们可以使用一样容易 std::unique_lock<std::mutex>
, 即使 std::unique_lock
不知道是什么my::mutex
是。
my::mutex
的激励性现实生活示例是提议std::shared_mutex
现在在 C++1y 中(我们希望 y == 4)draft standard . std::shared_mutex
有成员lock()
和 unlock()
用于独占模式锁定和解锁。它与 std::unique_lock
交互当客户端使用 std::unique_lock<std::shared_mutex>
正如预期的那样。
以防万一你可能相信shared_mutex
可能是唯一可以使用这个通用接口(interface)的其他激励互斥体,这是另一个真实世界的例子::-)
template <class L0, class L1>
void
lock(L0& l0, L1& l1)
{
while (true)
{
{
unique_lock<L0> u0(l0);
if (l1.try_lock())
{
u0.release();
break;
}
}
this_thread::yield();
{
unique_lock<L1> u1(l1);
if (l0.try_lock())
{
u1.release();
break;
}
}
this_thread::yield();
}
}
这是关于如何同时锁定(以异常安全的方式)两个 BasicLockables 而没有死锁危险的基本代码。尽管有许多相反的批评,但这段代码非常高效。
注意上面代码中的一行:
unique_lock<L0> u0(l0);
这个算法不知道什么类型L0
是。但是只要支持lock()
和 unlock()
(好的,try_lock()
也是),一切都很酷。 L0
甚至可能是 unique_lock
的另一个实例, 也许 unique_lock<my::mutex>
甚至 unique_lock<std::shared_mutex>
,甚至可能是 std::shared_lock<std::shared_mutex>
.
一切正常。都是因为std::unique_lock
之间没有亲密关系和 std::mutex
除了商定的公共(public)接口(interface) lock()
和 unlock()
.
关于c++ - 保持 std::mutex 锁定/解锁公开的基本原理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19761011/