怎么可能锁定一个GMutex两次?
How is it possible to lock a GMutex twice?
我有一个测试程序,我写了一个测试程序来尝试和调试我所拥有的GMutex问题,我似乎无法弄清楚。我使用下面的类来锁定和解锁一个作用域上下文中的互斥锁。这类似于BOOST的保护。
/// @brief Helper class used to create a mutex.
///
/// This helper Mutex class will lock a mutex upon creation and unlock when deleted.
/// This class may also be referred to as a guard.
///
/// Therefore this class allows scoped access to the Mutex's locking and unlocking operations
/// and is good practice since it ensures that a Mutex is unlocked, even if an exception is thrown.
///
class cSessionMutex
{
GMutex* apMutex;
/// The object used for logging.
mutable cLog aLog;
public:
cSessionMutex (GMutex *ipMutex) : apMutex(ipMutex), aLog ("LOG", "->")
{
g_mutex_lock(apMutex);
aLog << cLog::msDebug << "MUTEX LOCK " << apMutex << "," << this << cLog::msEndL;
}
~cSessionMutex ()
{
aLog << cLog::msDebug << "MUTEX UNLOCK " << apMutex << "," << this << cLog::msEndL;
g_mutex_unlock(apMutex);
}
};
使用这个类,我这样调用它:
bool van::cSessionManager::RegisterSession(const std::string &iSessionId)
{
cSessionMutex lRegistryLock (apRegistryLock);
// SOME CODE
}
其中apRegistryLock是GMutex*类型的成员变量,并且在我调用RegisterSession之前使用g_mutex_new()进行初始化。
话虽如此,当我运行带有多个线程的应用程序时,我有时会注意到,在开始的时候,当最初几次调用RegisterSession时,日志(来自上面的构造函数)
[DEBUG] LOG.-> - MUTEX LOCK 0x26abb40,0x7fc14ad7ae10
[DEBUG] LOG.-> - MUTEX LOCK 0x26abb40,0x7fc14af7ce10
在同一个互斥锁不同实例的一行中被记录两次;因此,建议互斥锁被锁定两次,或者第二个锁被忽略——这是非常糟糕的。
此外,值得注意的是,我还检查了这些日志是否是使用g_thread_self()函数从同一个线程发起的,这返回了两个单独的线程标识符;这表明互斥锁在不同的线程中被锁定了两次。
所以我的问题是,这怎么可能发生呢?
如果它在同一线程的同一调用链中被调用两次,则可能发生这种情况。第二个锁通常(尽管并非总是)被忽略。至少在pthreads中可以配置多个锁。
在我的情况下发生的事情是,有另一个线程使用相同的互斥锁调用g_cond_timed_wait函数,但互斥锁已解锁。在本例中,g_cond_timed_wait函数将未锁定的互斥锁解锁,并使互斥锁处于未定义状态,这解释了为什么我看到这个问题中解释的行为:互斥锁了两次。
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 运行同一解决方案的另一个项目的项目
- 挂起和取消挂起一个文件DLL
- 用C++中的一个变量定义一个常量
- 函数向量_指针有不同的原型,我可以构建一个吗
- 在c++中用vector填充一个简单的动态数组
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 预处理器:插入结构名称中的前一个行号
- 我在c++代码中生成了一个运行时#3异常
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 从链接列表c++中删除一个项目
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '