在C ++ 11标准中,unique_lock :: unlock是否未指定?

时间:2011-12-18 15:08:12

标签: c++ c++11

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.

所有其他锁定操作都指定至少两次抛出异常:

  • 互斥锁为NULL(使用system_error抛出errc::operation_not_permitted
  • 互斥锁已被锁定(使用system_error
  • 抛出errc::operation_not_permitted

unlock显然也存在无效互斥的问题,但是,该标准仅针对锁定问题指定了程序的行为。这是标准中的真正错误还是我遗漏了什么?

2 个答案:

答案 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)

pmmutex_typestd::mutex中解锁的定义是:

void unlock() noexcept;

也就是说,unlock函数不能抛出任何异常,因此unique_lock::unlock不必继承任何异常。至于为什么它可以抛出任何异常都是一个谜。

unique_lock的析构函数可能会抛出异常(因为我猜它可能需要调用unlock),这有点令人讨厌。这对我来说似乎很糟糕,因为在异常处理期间使用锁定对象来正确解锁是一种非常常见的习惯用法。在堆栈展开期间锁定可能会抛出异常非常糟糕 - 尤其是因为不允许使用底层互斥锁。

这里肯定是错的。

我还在上次公开草案中工作,也许这已经修好了