有没有办法判断C ++ 11中的当前线程是否锁定了互斥锁?特别是我想确保只有当调用线程保持对象的锁定(通过std::lock_guard
,std::unique_lock
或类似的东西)时才调用类中的某些函数,{{1成为成员变量。
为了避免在广泛使用对象时重复锁定和解锁,锁定std::mutex
的责任需要由调用者决定,并且不能在每个单独的函数中,并且如果当前线程不{1}}在调用任何这些函数时锁定,我想抛出异常。
似乎我不能只使用mutex
后跟解锁,因为mutex
的行为是未定义的,如果当前线程已经持有锁。
答案 0 :(得分:3)
我建议这样做的方法是让持有互斥锁时只能调用的函数引用std::unique_lock
或std::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 ++标准库中(目前)没有定义任何接口,允许您检查互斥锁是否已锁定且您是所有者。