tags:

views:

71

answers:

4

Please see the code below:

#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;
}

I don't know why console print out:

Must lock here
Why come here???

Does mutex not work? I want the result only show

Must lock here

And blocking after print the text above.

A: 

update: read up on mutexes in c++

I'm not a c++ expert, but a thread owns a mutex. In your example, the same thread opens/creates the named mutex so the second call will not block.

Have a look at this: "using mutex objects."

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

-Oisin

x0n
+2  A: 

No other thread other than your main thread has ownership of the mutex. This is the reason why it is not blocking and you see the two print statements. Following is an excerpt from the MSDN link which clearly explains how mutex works.

After a thread obtains ownership of a mutex, it can specify the same mutex in repeated calls to the wait-functions without blocking its execution. This prevents a thread from deadlocking itself while waiting for a mutex that it already owns. To release its ownership under such circumstances, the thread must call ReleaseMutex once for each time that the mutex satisfied the conditions of a wait function.

You may create multiple threads to see the blocking behavior in action. Note: Your code is also missing the ReleaseMutex call.

naivnomore
A: 

The "reason" it's not "working" is that there is no reason it should. The FALSE parameter says you are looking for an existing mutex, for one thing. Read the documentation. http://msdn.microsoft.com/en-us/library/ms682411%28VS.85%29.aspx

Are you sure you want a mutex rather than a CRITICAL_SECTION?

Jive Dadson
That's not what the second parameter means. "If this value is TRUE and the caller created the mutex, the calling thread obtains initial ownership of the mutex object. Otherwise, the calling thread does not obtain ownership of the mutex. To determine if the caller created the mutex, see the Return Values section." Passing false just means the created mutex isn't owned by the current thread when it is created.
Logan Capaldo
+1  A: 

If you want a synchronization primitive that behaves like you've described you can use an auto-reset event instead.

 #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;
 }
Logan Capaldo
I know how to Mutex work. Your answer is correct. Thank you :)
Tang Khai Phuong