为什么 std::lock 不使用全局排序来锁定互斥体?
Why doesn't `std::lock` lock mutexes using a global ordering?
std::lock
和 std::scoped_lock
可用于锁定一系列互斥锁,同时避免死锁。显然,他们使用了一些由 lock
s、try_lock
s 和 unlocks
组成的算法来实现这一点。
因为它应该更简单,所以 std::lock
和 std::scoped_lock
不能使用某种全局排序(例如使用 &
获取的地址)来锁定互斥体,作为当互斥锁总是以相同的顺序锁定时不会发生死锁?
该算法适用于任何可锁定对象——其中一些可能是其他锁的包装器(如 std::unique_lock
),因此检查地址是不够的。没有什么能阻止库识别所有涉及的类型都是来自标准库的“原始”锁并应用您的建议。
这可能会与其他算法发生死锁。假设一个锁保护一组对象,另一个锁保护该集合中的单个对象。不调用 std::lock
的代码将首先锁定集合,然后查找对象,然后想要获取保护该特定对象的锁。
如果使用了您的算法,那么如果对象中的代码使用 std::lock
获取两个锁并且您的算法要求先获取保护对象的锁,然后再获取保护集合的锁,会发生什么情况?会死锁。
std::lock
和 std::scoped_lock
可用于锁定一系列互斥锁,同时避免死锁。显然,他们使用了一些由 lock
s、try_lock
s 和 unlocks
组成的算法来实现这一点。
因为它应该更简单,所以 std::lock
和 std::scoped_lock
不能使用某种全局排序(例如使用 &
获取的地址)来锁定互斥体,作为当互斥锁总是以相同的顺序锁定时不会发生死锁?
该算法适用于任何可锁定对象——其中一些可能是其他锁的包装器(如 std::unique_lock
),因此检查地址是不够的。没有什么能阻止库识别所有涉及的类型都是来自标准库的“原始”锁并应用您的建议。
这可能会与其他算法发生死锁。假设一个锁保护一组对象,另一个锁保护该集合中的单个对象。不调用 std::lock
的代码将首先锁定集合,然后查找对象,然后想要获取保护该特定对象的锁。
如果使用了您的算法,那么如果对象中的代码使用 std::lock
获取两个锁并且您的算法要求先获取保护对象的锁,然后再获取保护集合的锁,会发生什么情况?会死锁。