此设计决策的基本原理记录在N2406中:
与 boost 不同,互斥锁具有用于 lock()、unlock() 等的公共成员函数。这是支持主要目标之一所必需的:用户定义的互斥锁可以与标准定义的锁一起使用。如果用户定义的互斥锁没有接口来实现,那么标准定义的锁就无法与用户定义的互斥锁进行通信。
在撰写本文时,boost::mutex 只能使用 boost::scoped_lock 锁定和解锁。
所以你现在可以写作my::mutex
了,只要你提供会员lock()
,unlock()
你my::mutex
就是一等公民std::mutex
。您的客户可以像使用std::unique_lock<my::mutex>
一样轻松使用std::unique_lock<std::mutex>
,即使std::unique_lock
不知道是什么my::mutex
。
现在在 C++1y (我们希望 y == 4)草案标准my::mutex
中提出了一个鼓舞人心的现实生活示例。 拥有会员并为独占模式锁定和解锁。并且它与客户端按预期使用时进行交互。std::shared_mutex
std::shared_mutex
lock()
unlock()
std::unique_lock
std::unique_lock<std::shared_mutex>
并且以防万一您可能认为shared_mutex
可能是唯一可以使用此通用接口的其他激励互斥锁,这是另一个真实世界的示例::-)
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
lock()
unlock()