boost的递归锁

引用之前发表过的文章: http://lajabs.blog.cd/?p=342
针对如下错误:
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector >'
what(): boost::lock_error

在之后不断地资料查找中发现官方解释如下,这是一系列的锁检测机制:

Checked Locking Strategy

With a checked locking strategy, when a thread attempts to acquire a lock on the mutex object for which the thread already owns a lock, the operation will fail with some sort of error indication. Further, attempts by a thread to unlock a mutex object that was not locked by the thread will also return some sort of error indication. In Boost.Thread, an exception of type boost::lock_error would be thrown in these cases.

Boost.Thread does not currently provide any mutex objects that use this strategy.

Unchecked Locking Strategy

With an unchecked locking strategy, when a thread attempts to acquire a lock on a mutex object for which the thread already owns a lock the operation will deadlock. In general this locking strategy is less safe than a checked or recursive strategy, but it's also a faster strategy and so is employed by many libraries.

Boost.Thread does not currently provide any mutex objects that use this strategy.

Unspecified Locking Strategy

With an unspecified locking strategy, when a thread attempts to acquire a lock on a mutex object for which the thread already owns a lock the operation results in undefined behavior.

In general a mutex object with an unspecified locking strategy is unsafe, and it requires programmer discipline to use the mutex object properly. However, this strategy allows an implementation to be as fast as possible with no restrictions on its implementation. This is especially true for portable implementations that wrap the native threading support of a platform. For this reason, the classes boost::mutex, boost::try_mutex and boost::timed_mutex use this locking strategy despite the lack of safety.

上面简单的意思是:
使用Checked Locking Strategy (检测策略)时发生死锁会抛出“boost::lock_error ”的异常。
boost没有提供Unchecked Locking Strategy (非检测策略) 相关的锁。
使用Unspecified Locking Strategy (未定义策略)结果是未定义的。

注意boost::mutex使用的是Unspecified Locking Strategy 未定义的检测机制,也就是说它既可能死锁,也可能是抛出“boost::lock_error ”的异常,这对程序的调试会带来许多不确定因素。

所以建议根据情况尽可能地使用recursive_mutex,它使用的是Recursive Locking Strategy,具体描述如下:

With a recursive locking strategy, when a thread attempts to acquire a lock on the mutex object for which it already owns a lock, the operation is successful. Note the distinction between a thread, which may have multiple locks outstanding on a recursive mutex object, and a lock object, which even for a recursive mutex object cannot have any of its lock functions called multiple times without first calling unlock.

Internally a lock count is maintained and the owning thread must unlock the mutex object the same number of times that it locked it before the mutex object's state returns to unlocked. Since mutex objects in Boost.Thread expose locking functionality only through lock concepts, a thread will always unlock a mutex object the same number of times that it locked it. This helps to eliminate a whole set of errors typically found in traditional C style thread APIs.

Classes boost::recursive_mutex, boost::recursive_try_mutex and boost::recursive_timed_mutex use this locking strategy.

它就是常说的可重入的递归锁,可以最大程度避免死锁的发生,当然需要付出一些效率上的代价(基本可以接受),但对于保证整个程序健壮性而言是非常值得的。

使用方法:

boost::recursive_mutex mtx;
boost::recursive_mutex::scoped_lock
lock(mtx);

  

posted @ 2011-07-19 11:44  lajabs  阅读(2159)  评论(0编辑  收藏  举报