我写了以下代码来测试我的理解std::mutex
int main() {
mutex m;
m.lock();
m.lock(); // expect to block the thread
}
然后我得到了一个system_error: device or resource busy
. 第二个不m.lock()
应该阻塞线程吗?
我写了以下代码来测试我的理解std::mutex
int main() {
mutex m;
m.lock();
m.lock(); // expect to block the thread
}
然后我得到了一个system_error: device or resource busy
. 第二个不m.lock()
应该阻塞线程吗?
来自std::mutex
:
调用线程在调用 lock 或 try_lock 之前不得拥有互斥锁。
如果锁被已经拥有互斥锁的线程调用,程序可能会死锁。或者,如果实现可以检测到死锁,则可以观察到 resource_deadlock_would_occur 错误情况。
和例外条款:
当错误发生时抛出 std::system_error,包括来自底层操作系统的错误,这些错误会阻止锁满足其规范。在抛出任何异常的情况下,互斥锁不会被锁定。
因此它不应该阻塞线程。在您的平台上,实现似乎能够检测线程何时已经是锁的所有者并引发异常。如描述中所示,这可能不会在其他平台上发生。
第二个不
m.lock()
应该阻塞线程吗?
不,它给出了未定义的行为。第二个m.lock()
打破了这个要求:
C++11 30.4.1.2/7要求:如果 m 是
std::mutex
or类型std::timed_mutex
,则调用线程不拥有互斥锁。
看起来您的实现能够检测到调用线程拥有互斥锁并给出错误;其他人可能会无限期地阻塞,或者以其他方式失败。
(std::mutex
当我写这个答案时,问题中没有提到。)
这取决于您使用的互斥库和互斥类型 - 您还没有告诉我们。一些系统提供了一个“递归互斥锁”,只有当它发生在同一个线程中时才允许多次调用它(那么在另一个线程可以锁定它之前,你必须有匹配数量的解锁),其他库认为这是一个错误并且可能会优雅地失败(就像你的那样)或有未定义的行为。