为什么锁定std :: mutex不会阻塞线程

时间:2013-05-21 07:24:55

标签: c++ c++11 concurrency

我编写了以下代码来测试我对std::mutex

的理解
int main() {
    mutex m;
    m.lock();
    m.lock(); // expect to block the thread
}

然后我得到了system_error: device or resource busy。是不是第二个m.lock()应该阻止线程?

3 个答案:

答案 0 :(得分:14)

来自std::mutex

  

在调用lock或try_lock之前,调用线程不得拥有互斥锁。

std::mutex::lock

  

如果已经拥有互斥锁的线程调用了锁,则程序可能会死锁。或者,如果实现可以检测到死锁,则可能会观察到resource_deadlock_would_occur错误情况。

例外子句:

  

发生错误时抛出std :: system_error,包括来自底层操作系统的错误,这些错误会阻止锁定符合其规范。在抛出任何异常的情况下,互斥锁不会被锁定。

因此不应该阻止线程。在您的平台上,实现似乎能够检测线程何时已经是锁的所有者并引发异常。如描述中所示,这可能不会发生在其他平台上。

答案 1 :(得分:8)

  

是不是第二个m.lock()应该阻止线程?

不,它给出了未定义的行为。第二个m.lock()打破了这一要求:

  

C ++ 11 30.4.1.2/7 要求:如果m的类型为std::mutexstd::timed_mutex,则调用线程不拥有互斥锁。

看起来您的实现能够检测到调用线程拥有互斥锁并发出错误;其他人可能无限期阻止,或以其他方式失败。

答案 2 :(得分:2)

(当我写这个答案时,问题中没有提及std::mutex。)

这取决于您使用的互斥库和互斥锁类型 - 您还没有告诉我们。有些系统提供了一个递归的互斥体"只有当它从同一个线程发生时才允许被多次调用(然后你必须在另一个线程可以锁定之前有一个匹配的解锁数),其他库认为这是一个错误并且可能会优雅地失败(因为你的)或有不明确的行为。