为什么 libc++ 允许 std::mutex 的递归锁定?

Why does libc++ allow recursive locking of std::mutex?

std::mutex 是非递归的,违反它是 UB。所以理论上一切皆有可能(包括作为 std::recursive_mutex)),但是 libc++ seems to work fine ,这个程序输出

bye

#include <iostream>
#include <mutex>

std::mutex m;
int main() {
    std::scoped_lock l1(m);
    std::scoped_lock l2(m);
    std::cout << "bye" << std::endl;
}

这是 libc++ 中的故意设计决定还是只是一些意外(例如,他们可以对互斥和 recursive_mutex 使用相同的逻辑)?

libstdc++ 挂起。

注意:我知道人们不应该依赖 UB,所以这与最佳实践无关,我只是对模糊的实现细节感到好奇。

这似乎不是有意设计的决定。 std::mutex 的 libc++ 实现只是平台的 POSIX 默认互斥锁的包装器。由于如果递归锁定也被定义为具有 UB,它们只是继承了平台的默认 POSIX 互斥体也恰好允许递归锁定的事实。

我得到相反的结果:libc++ 挂起而 libstdc++ 没有挂起

原因是如果文件未使用 -pthread 编译,线程支持将被禁用并且 std::mutex::lock/unlock 成为 noops。添加 -pthread 使它们都如预期的那样死锁。

libc++ 默认使用线程支持构建,不需要 -pthread 标志,因此它 std::mutex::lock 实际上会获取锁,从而造成死锁。