Блокировка и синхронизация с помощью Mutex - PullRequest
0 голосов
/ 30 марта 2012

Я создаю программу, которая будет выполнять одну и ту же функцию в нескольких процессах и нескольких потоках, поэтому я создал функцию для достижения блокировки и синхронизации, которая составляет

HANDLE WaitOnMutex(char* mt)
{
    HANDLE ghMutex=NULL; 
    DWORD lastError=-1;
    do
    {
        ghMutex = CreateMutex(NULL,TRUE,mt);
        lastError=  GetLastError();
        if(lastError!=ERROR_SUCCESS)
        {
            CloseHandle(ghMutex);
            Sleep(2000);
        }
    }
    while(lastError!=ERROR_SUCCESS);
    return ghMutex;
}

и я использую его следующим образом

    HANDLE mtx=WaitOnMutex("Global\\DBG_MY_APP");
    //Do the work that needs sync
    CloseHandle(mtx)

Это правильный способ заблокировать эту функцию? или мне нужно использовать другой метод ..

Примечание: я использую "Global", потому что некоторые части моего приложения - winService, и мне нужно заблокировать между изолированными сессией процессами

Код работает в среде тестирования, но я не уверен, правильно ли я это делаю

Ответы [ 2 ]

4 голосов
/ 30 марта 2012

То, что вы кодировали, - это занятое ожидание, которое в большинстве случаев не идеально.Не только это, но вы обернули это в тяжелые вызовы создания и освобождения мьютекса.

Чтобы использовать именованный мьютекс для межпроцессной синхронизации, каждый процесс должен вызывать CreateMutex только один раз.Затем вы держите дескриптор мьютекса и используете WaitForSingleObject, чтобы дождаться его, и ReleaseMutex, чтобы снять блокировку.Затем вы можете снова заблокировать его с помощью WaitForSingleObject в следующий раз, когда вам понадобится доступ к защищенному ресурсу, и т. Д.

Когда ваш процесс завершается с мьютексом «навсегда» (например, потому что процесс завершается), тогдаВы звоните CloseHandle.

2 голосов
/ 30 марта 2012

Полагаю, это будет своего рода работа для достаточно свободного определения понятия "работа".Это не то, как я выполняю эту работу.

Я думаю, я бы сделал что-то вроде этого:

Где-то в единовременном коде инициализации:

HANDLE mutex = CreateMutex(name); // yes, there are more parameters here.

Затем записать в журнал:

WaitForSingleObject(mutex, INFINITE);

// write to log

ReleaseMutex(handle);

Затем во время одноразового кода выключения:

CloseHandle(mutex);

Если вы используете C ++ вместо C, вы обычно хотитеобработайте это через RAII, так что вы создадите объект журнала, который выполняет вызов CreateMutex в своем ctor, а вызов CloseHandle в этом dtor.Тогда у вас будет функтор записи, который выполняет WaitForSingleObject в своем ctor, записывает в журнал его operator() и выполняет ReleaseMutex в своем dtor.Это сохраняет большую часть вашего кода относительно простым и обеспечивает безопасность исключений практически без дополнительной работы.

...