Можно ли сделать статическую инициализацию мьютексов в Windows? - PullRequest
6 голосов
/ 24 августа 2010

pthread поддерживает статическую инициализацию pthread_mutex_t с использованием PTHREAD_MUTEX_INITIALIZER.

Возможно ли добиться аналогичного статического механизма инициализации мьютекса с использованием мьютекса Windows?

Ответы [ 2 ]

7 голосов
/ 29 февраля 2012

Да, это возможно с помощью нескольких строк кода. Вот порт pthread-совместимых операций мьютекса, включая статический инициализатор MUTEX_INITIALIZER, который вы хотите:

#define MUTEX_TYPE             HANDLE
#define MUTEX_INITIALIZER      NULL
#define MUTEX_SETUP(x)         (x) = CreateMutex(NULL, FALSE, NULL)
#define MUTEX_CLEANUP(x)       (CloseHandle(x) == 0)
#define MUTEX_LOCK(x)          emulate_pthread_mutex_lock(&(x))
#define MUTEX_UNLOCK(x)        (ReleaseMutex(x) == 0)

int emulate_pthread_mutex_lock(volatile MUTEX_TYPE *mx)
{ if (*mx == NULL) /* static initializer? */
  { HANDLE p = CreateMutex(NULL, FALSE, NULL);
    if (InterlockedCompareExchangePointer((PVOID*)mx, (PVOID)p, NULL) != NULL)
      CloseHandle(p);
  }
  return WaitForSingleObject(*mx, INFINITE) == WAIT_FAILED;
}

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

2 голосов
/ 24 августа 2010

Нет, поскольку мьютекс Windows является дескриптором, его необходимо инициализировать с помощью CreateMutex().

Обратите внимание, что статическая инициализация pthread_mutex_t с использованием PTHREAD_MUTEX_INITIALIZER не является настоящей инициализацией, этобудет сделано внутри при первом вызове pthread_mutex_lock() или pthread_mutex_trylock()

...