11

我写了以下代码来测试我的理解std::mutex

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

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

4

3 回答 3

15

来自std::mutex

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

并从std::mutex::lock

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

例外条款:

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

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

于 2013-05-21T07:27:48.463 回答
9

第二个不m.lock()应该阻塞线程吗?

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

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

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

于 2013-05-21T07:36:27.373 回答
2

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

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

于 2013-05-21T07:26:51.877 回答