如何断言std :: mutex是否被锁定? [英] How to assert if a std::mutex is locked?

查看:561
本文介绍了如何断言std :: mutex是否被锁定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用GCC 4.8.2(在Linux / Debian / Sid 64位上) - 或GCC 4.9(如果可用) - 在C ++ 11中 - 我有一些互斥

  std :: mutex gmtx; 

其实,它是一个 static alpha beta 的某些类 Foo


$

$ <$ p $

  void alpha(void){
std :: lock_guard< std :: mutex> g(gmtx);
beta(void);
//其他工作
}

code> beta 确实 gmtx 已锁定:

  void beta(void){
assert(gmtx.is_locked());
//一些真正的工作
}

code> is_locked 仅在 assert ...内调用...它可能非常低效甚至有时不准确) p>

当然,我有其他函数调用 beta ,例如

  void gamma(void){
std :: lock_guard< std :: mutex> g(gmtx);
beta();
//其他工作
}

is_locked 不存在....我应该如何定义它? (实际上我想确保mutex已被一些[间接]调用者锁定在同一个线程中)



(我想测试的原因 assert beta 可以在其他地方调用)



我不能使用 try_lock (除非使用递归互斥体),因为在通常情况下,它将锁定一个已经锁定的互斥体...(锁定在同一个线程中的调用者)



我想避免递归互斥(比纯互斥更贵),除非我真的需要。






注意:真正的程序有点复杂。实际上,所有的方法都在一个类中,在items上保持命名双向关系。所以我在这个类内有一个从地图项到地名,另一个从地名到地图。 beta 将是添加真正命名的内部方法, alpha gamma

PS:

真正的程序尚未发布,但应成为 MELT - 其未来的一部分监视;您可以从这里(临时位置)下载(alpha阶段,非常错误)

解决方案

std :: unique_lock< L> owns_lock 成员函数(相当于 is_locked )。

  std :: mutex gmtx; 
std :: unique_lock< std :: mutex> glock(gmtx,std :: defer_lock);

void alpha(void){
std :: lock_guard< decltype(glock)> g(glock);
beta(void);
//其他工作
}
void beta(void){
assert(glock.owns_lock()); //或者assert(glock);
//一些实际工作
}

strong>在此解决方案中,所有锁定操作都应通过unique_lock glock 而不是'raw'mutex gmtx 执行。例如, alpha 成员函数被重写为 lock_guard (或简单地 lock_guard< decltype(glock)> )。


With GCC 4.8.2 (on Linux/Debian/Sid 64 bits) -or GCC 4.9 when available - in C++11- I have some mutex

std::mutex gmtx;

actually, it is a static member in some class Foo containing both alpha and beta methods below.

it is locked in alpha like

void alpha(void) {
   std::lock_guard<std::mutex> g(gmtx);
   beta(void);
   // some other work
}

and I want to check in beta that indeed gmtx is locked:

void beta(void) {
   assert (gmtx.is_locked());
   // some real work
}

(notice that is_locked is only called inside assert... It can be very inefficient or even sometimes inaccurate)

Of course, I have other functions calling beta, e.g.

void gamma(void) {
   std::lock_guard<std::mutex> g(gmtx);
   beta();
   // some other work
}

but is_locked does not exist.... How should I define it? (actually I would like to be sure that the mutex has been locked in the same thread by some [indirect] caller...)

(the reason I want to test that with assert is that beta could be called elsewhere)

I cannot use try_lock (unless using recursive mutexes), because in the common case it would lock an already locked mutex... (locked in the same thread by a caller) and this is not only undefined behavior but blocks entirely.

I want to avoid recursive mutexes (more costly than plain mutexes) unless I really have to.


NB: The real program is a bit more complex. Actually, all the methods are inside a class which maintain a naming bi-directional relation on "items". So I have inside that class a map from items to names and another from names to items. beta would be the internal method adding really a naming, and alpha and gamma would be the methods finding -or adding- an item by its name, or a name by its item.

PS: the real program is not yet released, but should become part of MELT - its future monitor; you can download it (alpha stage, very buggy) from here (a temporary location)

解决方案

std::unique_lock<L> has owns_lock member function (equivalent of is_locked as you say).

std::mutex gmtx;
std::unique_lock<std::mutex> glock(gmtx, std::defer_lock);

void alpha(void) {
   std::lock_guard<decltype(glock)> g(glock);
   beta(void);
   // some other work
}
void beta(void) {
   assert(glock.owns_lock()); // or just assert(glock);
   // some real work
}

EDIT: In this solution, all lock operations should be performed via unique_lock glock not 'raw' mutex gmtx. For example, alpha member function is rewritten with lock_guard<unique_lock<mutex>> (or simply lock_guard<decltype(glock)>).

这篇关于如何断言std :: mutex是否被锁定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆