【发布时间】:2014-02-19 21:33:23
【问题描述】:
使用 GCC 4.8.2(在 Linux/Debian/Sid 64 位上)-或 GCC 4.9(如果可用)-在 C++11 中-我有一些互斥体
std::mutex gmtx;
实际上,它是某个类Foo 中的static 成员,其中包含alpha 和beta 下面的方法。
它被锁定在alphalike
void alpha(void) {
std::lock_guard<std::mutex> g(gmtx);
beta(void);
// some other work
}
我想检查beta 确实gmtx 已锁定:
void beta(void) {
assert (gmtx.is_locked());
// some real work
}
(注意is_locked 只在assert 内部调用...可能效率非常低,甚至有时不准确)
当然,我还有其他函数调用beta,例如
void gamma(void) {
std::lock_guard<std::mutex> g(gmtx);
beta();
// some other work
}
但是is_locked 不存在....我应该如何定义它? (实际上我想确保互斥锁已被某些 [indirect] 调用者锁定在同一个线程中......)
(我想用assert 进行测试的原因是beta 可以在其他地方调用)
我不能使用try_lock(除非使用递归互斥锁),因为在常见情况下它会锁定一个已经锁定的互斥锁...(被调用者锁定在同一个线程中)这不仅是未定义的行为,而且会阻塞完全。
我想避免递归互斥锁(比普通互斥锁更昂贵),除非我真的必须这样做。
注意:真正的程序有点复杂。实际上,所有方法都在一个类中,该类在“项目”上保持命名双向关系。所以我在那个类里面有一个从项目到名称的映射和另一个从名称到项目的映射。 beta 将是添加真正命名的内部方法,alpha 和 gamma 将是通过项目名称或项目名称查找或添加项目的方法。
PS:真正的程序还没有发布,但应该成为MELT的一部分——它的未来monitor;您可以从here(临时位置)下载它(alpha 阶段,非常错误)
【问题讨论】:
-
如果
beta要求互斥锁始终处于锁定状态(正如您的assert所建议的那样),您为什么要将该责任推到调用链上? -
因为(正如我编辑的那样)像
gamma这样的其他函数会调用beta... -
是的,我明白了,但是两者都需要在调用 beta 之前锁定互斥锁,那么为什么 beta 不只是锁定互斥锁呢?你是说两个调用者都有其他需要锁定互斥锁的工作吗?
-
@JohnLedbetter:是的,两个调用者都在做真正的工作。
-
将锁包装在一个维护“锁定”布尔变量的类中并检查?