来自 CPPReference ,没有明确说明如果锁定不会导致死锁,则 std::mutex
的锁定函数不会抛出。
PThread's lock只有死锁错误。我不知道窗口对线程的实现。我也不知道它们是否是用作 std::thread
/std::mutex
后端的线程的其他实现。
所以我的问题是“我是否应该编写我的代码,就好像有时候,由于没有特殊原因,锁定可能会失败?”。
我实际上需要在某些 noexcept 方法中锁定一个互斥量,并且我想确保它们是 noexcept。
最佳答案
std::mutex::lock()
成员函数未声明为 noexcept
并且来自 30.4.1.2 Mutex types 部分c++11 标准(草案 n3337),第 6 条:
The expression
m.lock()
shall be well-formed and have the following semantics:
- ...
- Throws:
system_error
when an exception is required (30.2.2).- Error conditions:
operation_not_permitted
— if the thread does not have the privilege to perform the operation.resource_deadlock_would_occur
— if the implementation detects that a deadlock would occur.device_or_resource_busy
— if the mutex is already locked and blocking is not possible.
这意味着任何使用 mutex::lock()
的函数都不能被标记为 noexcept
,除非该函数本身能够处理异常并阻止它传播给来电者。
我无法评论这些错误情况发生的可能性,但与 std::mutex
和 resource_deadlock_would_occur
(可能 被抛出)它表示代码中的错误而不是运行时失败,因为如果线程尝试锁定 std::mutex
它可能会引发此错误已经拥有。来自30.4.1.2.1 类互斥部分,第 4 条:
[ Note: A program may deadlock if the thread that owns a mutex object calls lock() on that object. If the implementation can detect the deadlock, a resource_deadlock_would_occur error condition may be observed. —end note ]
通过选择 std::mutex
作为锁类型,程序员明确声明同一线程尝试锁定它已经锁定的 mutex
是不可能的.
如果线程重新锁定 mutex
然后是 std:recursive_mutex
是合法的执行路径是更合适的选择(但更改为 recursive_lock
并不意味着 lock()
函数没有异常)。
关于c++ - 即使一切看起来都是 "good", std::mutex::lock 也会抛出吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17551256/