2016-07-19 59 views
0

为什么std::mutex::unlock()不是noexept?由于某些原因,当不拥有互斥锁的线程在其上调用unlock()时,标准会使行为不确定。这样做的理由是什么?这不会导致std::unique_lockstd::lock_guard析构函数在函数抛出时意外地在析构函数中泄漏异常吗?为什么std :: mutex :: unlock()不是noexcept

析构函数抛出 - https://akrzemi1.wordpress.com/2011/09/21/destructors-that-throw/

+2

我认为这只是委员会政策的一个结果,即非常谨慎地应用noexcept,并且只在对性能和/或实现基本/强大例外保证至关重要的情况下应用。 – MikeMB

回答

2

我不能说为什么委员会没有把它做成noexcept。我只能指出noexcept通常只在整个标准库中显式应用于实现高效功能(例如std::swap或移动构造函数)所必需的几个关键函数。

至于std::unique_lock关注但是:它的析构函数(隐含)noexcept,所以如果实现将允许解锁扔,unique_lock的析构函数必须抓住它的内部。

+1

不是。 'BasicLockable'需要'unlock()'不会抛出,所以如果抛出所有的赌注都关闭 - 'terminate'实际上是一个很好的选择。 'unlock()'不是'noexcept',因为它是狭义的合约。试图解锁你不拥有的互斥体会导致UB,并且一个实现可能想要抛出异常(例如,在调试模式下),如果它可以检测到的话。 –

0

std::unique_lock有一个标志来表明它是“拥有”的锁。一旦你成功呼叫lock,它就会设置标志。当您拨打unlock时,该标志将被重置。

当析构函数被调用时,如果它没有锁,它将不会调用unlock

+0

谢谢!那就对了。但'lock_guard'会发生什么情况? – Curious

+0

在'lock_guard'的构造函数中,它'锁定''mutex',即构造函数的参数。所以'lock_guard'总是'拥有''互斥'。当它破坏时,它必须“解锁”它所拥有的“互斥量”。 –

相关问题