WaitForSingleObject не работает - PullRequest
2 голосов
/ 24 августа 2010

Пожалуйста, смотрите код ниже:

#include <windows.h>
int main(int argc, char* argv[])
{
    HANDLE _mutex = ::CreateMutex(NULL, FALSE, "abc");
    if (!_mutex)
        throw std::runtime_error("CreateMutex failed");

    if (::WaitForSingleObject(_mutex, INFINITE) != WAIT_OBJECT_0)
        throw std::runtime_error("WaitForSingleObject failed");

    printf("Must lock here\n");

    if (::WaitForSingleObject(_mutex, INFINITE) != WAIT_OBJECT_0)
        throw std::runtime_error("WaitForSingleObject failed");

    printf("Why come here????\n");
    return 0;
}

Я не знаю, почему распечатывается консоль:

Must lock here
Why come here???

Не работает ли мьютекс?Я хочу, чтобы результат показывал только

Must lock here

и блокировку после печати текста выше.

Ответы [ 4 ]

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

Никакой другой поток, кроме вашего основного потока, не владеет мьютексом. Это причина, по которой он не блокируется, и вы видите два оператора печати. Ниже приводится выдержка из ссылки на MSDN, которая четко объясняет , как работает мьютекс .

После того, как поток получает право собственности на мьютекс, он может указывать тот же мьютекс в повторных звонках на функции ожидания, не блокируя его выполнение. Это предотвращает поток от заблокировать себя в ожидании мьютекс, которым он уже владеет. Выпустить его собственность под таким обстоятельства, поток должен вызвать ReleaseMutex один раз за каждый раз, когда мьютекс удовлетворял условиям функция ожидания.

Вы можете создать несколько потоков, чтобы увидеть поведение блокировки в действии. Примечание. В вашем коде также отсутствует вызов ReleaseMutex .

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

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

 #include <windows.h>
 #include <stdexcept>
 #include <stdio.h>
 int main(int argc, char* argv[])
 {
     HANDLE _mutex = ::CreateEvent(NULL, FALSE,         TRUE, NULL);
                                         // auto reset  // initially signalled
     if (!_mutex)
         throw std::runtime_error("CreateEvent failed");

     if (::WaitForSingleObject(_mutex, INFINITE) != WAIT_OBJECT_0) 
         throw std::runtime_error("WaitForSingleObject failed");
     // unsignalled now

     printf("Must lock here\n");

     // will block forever until someone calls SetEvent
     if (::WaitForSingleObject(_mutex, INFINITE) != WAIT_OBJECT_0)
         throw std::runtime_error("WaitForSingleObject failed");

     printf("Why come here????\n");
     return 0;
 }
0 голосов
/ 24 августа 2010

«Причина», по которой он не «работает», заключается в том, что нет причины, по которой это следует Параметр FALSE говорит, что вы ищете существующий мьютекс, с одной стороны. Прочитайте документацию. http://msdn.microsoft.com/en-us/library/ms682411%28VS.85%29.aspx

Вы уверены, что хотите мьютекс, а не CRITICAL_SECTION?

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

обновление: чтение мьютексов в c ++

Я не эксперт по c ++, но потоку принадлежит мьютекс.В вашем примере тот же поток открывает / создает именованный мьютекс, поэтому второй вызов не будет блокироваться.

Посмотрите на это: «использование объектов мьютекса».

http://msdn.microsoft.com/en-us/library/ms686927(v=VS.85).aspx

-Oisin

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...