我有一个测试程序,我写的是尝试调试我所拥有的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()函数从同一个线程启动的,并返回两个单独的线程标识符;因此,建议互斥锁被锁定两次来自不同的线程。
所以我的问题是,这怎么可能发生?
答案 0 :(得分:2)
如果它在同一个线程中的同一个调用链中被调用两次,则可能发生这种情况。第二个锁通常(但不总是)被忽略。至少在pthreads中,可以将多个锁配置为计数。
答案 1 :(得分:0)
在我的情况下发生的事情是有另一个线程使用相同的互斥锁调用g_cond_timed_wait函数,但互斥锁已解锁。在这种情况下,g_cond_timed_wait函数解锁未锁定的互斥锁并使互斥锁处于未定义状态,这解释了为什么我看到此问题中解释的行为:互斥锁被锁定两次。