确保当前线程锁定C ++ 11互斥锁

时间:2015-03-03 06:51:01

标签: c++ multithreading c++11 locking mutex

有没有办法判断C ++ 11中的当前线程是否锁定了互斥锁?特别是我想确保只有当调用线程保持对象的锁定(通过std::lock_guardstd::unique_lock或类似的东西)时才调用类中的某些函数,{{1成为成员变量。

为了避免在广泛使用对象时重复锁定和解锁,锁定std::mutex的责任需要由调用者决定,并且不能在每个单独的函数中,并且如果当前线程不

似乎我不能只使用mutex后跟解锁,因为mutex的行为是未定义的,如果当前线程已经持有锁。

2 个答案:

答案 0 :(得分:3)

我建议这样做的方法是让持有互斥锁时只能调用的函数引用std::unique_lockstd::lock_guard。在unique_lock的情况下,您可能还想断言它实际上持有锁。

这将利用编译器来强制执行您的要求。

据推测,这些函数对于您的类是内部/私有的,并且您具有获取锁定然后调用这些函数的面向用户的函数。如果是这样,有一个额外的参数不会污染面向用户的API。

这些方面的东西:

// public
void A::public_function() {
   std::lock_guard<std::mutex> l(m_mutex);
   // ... do stuff
   b(l);
   // ... do more stuff
}

// private
void A::b(std::lock_guard const& l) {
   // ... do stuff that requires holding the mutex
}

如果您需要使用unique_lock,只需断言您的函数中l.owns_lock()为真(如果您想抛出异常)。

我对递归互斥体的体验是,它们可以轻松地将您的锁定策略和所有权视为应有的严重程度。他们最后可能会咬你。请参阅this帖子。

答案 1 :(得分:1)

只需在代码中使用recursive mutex并锁定/解锁,就像没有保证上层锁定一样。然后将mutex也提供给可以使用它(或不使用)的调用代码。

最重要的是,如果上层没有锁定,您的代码仍然可以正常工作,但速度可能会降低。如果上层确实锁定了,那么这将是一个检查,如果它拥有锁和一个refcount增量/减量,与你计划做的事情类似的开销。

C ++标准库中(目前)没有定义任何接口,允许您检查互斥锁是否已锁定且您是所有者。