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