此设计决策的基本原理记录在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_mutexstd::shared_mutexlock()unlock()std::unique_lockstd::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::mutexlock()unlock()