Как можно заблокировать GMutex дважды? - PullRequest
0 голосов
/ 07 апреля 2011

У меня есть тестовая программа, которую я написал, чтобы попытаться отладить проблему 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 * и инициализируется с помощью g_mutex_new() прежде, чем я вызову RegisterSession.

С учетом сказанного, когда я запускаю приложение с несколькими потоками, я иногда замечаю в начале, когда RegisterSession вызывается в первые несколько раз, когда журнал (из конструктора)выше)

[DEBUG] LOG.-> - MUTEX LOCK 0x26abb40,0x7fc14ad7ae10
[DEBUG] LOG.-> - MUTEX LOCK 0x26abb40,0x7fc14af7ce10

регистрируется дважды подряд с одним и тем же мьютексом, но с другим экземпляром;следовательно, предположение, что мьютекс блокируется дважды или просто игнорируется вторая блокировка - что очень плохо.

Более того, стоит отметить, что я также проверяю, были ли эти журналы инициированы из одного и того же потока с помощью функции g_thread_self (), и это вернуло два отдельных идентификатора потока;таким образом, предполагая, что мьютекс был заблокирован дважды из отдельных потоков.

Итак, мой вопрос: как это возможно?

Ответы [ 2 ]

2 голосов
/ 07 апреля 2011

Если он вызывается дважды в одной цепочке вызовов в одном и том же потоке, это может произойти. Второй замок обычно (хотя и не всегда) игнорируется. По крайней мере, в pthreads можно настроить несколько блокировок в расчете.

0 голосов
/ 07 апреля 2011

В моем случае происходило то, что был другой поток, который вызывал функцию g_cond_timed_wait с тем же мьютексом, но с мьютексом разблокированным.В этом случае функция g_cond_timed_wait разблокирует мьютекс, который не заблокирован, и оставляет мьютекс в неопределенном состоянии, что объясняет, почему я видел поведение, объясненное в этом вопросе: мьютекс был заблокирован дважды.

...