C ++ 11标准将unique_lock::unlock
定义为(§30.4.2.2.2,第1159页)
void unlock();
Effects: pm->unlock()
Postcondition: owns == false
Throws: system_error when an exception is required (30.2.2).
Error conditions:
— operation_not_permitted — if on entry owns is false.
所有其他锁定操作都指定至少两次抛出异常:
system_error
抛出errc::operation_not_permitted
)system_error
)errc::operation_not_permitted
unlock
显然也存在无效互斥的问题,但是,该标准仅针对锁定问题指定了程序的行为。这是标准中的真正错误还是我遗漏了什么?
答案 0 :(得分:7)
虽然未明确说明,但unique_lock
具有以下不变量:
if pm == nullptr then owns == false
if owns == true then pm != nullptr
除了未定义的行为之外,没有办法让unique_lock
进入违反这些不变量的状态。所以条款:
— operation_not_permitted — if on entry owns is false.
涵盖了pm == nullptr
。
请注意,如果~unique_lock()
为真,pm->unlock()
只会调用owns
。如果owns
为真,则pm != nullptr
因此unlock()
无法投放。
答案 1 :(得分:0)
pm
是mutex_type
,std::mutex
中解锁的定义是:
void unlock() noexcept;
也就是说,unlock
函数不能抛出任何异常,因此unique_lock::unlock
不必继承任何异常。至于为什么它可以抛出任何异常都是一个谜。
unique_lock
的析构函数可能会抛出异常(因为我猜它可能需要调用unlock
),这有点令人讨厌。这对我来说似乎很糟糕,因为在异常处理期间使用锁定对象来正确解锁是一种非常常见的习惯用法。在堆栈展开期间锁定可能会抛出异常非常糟糕 - 尤其是因为不允许使用底层互斥锁。
这里肯定是错的。
我还在上次公开草案中工作,也许这已经修好了