CreateMutex 一个命名的 mutex, 如果此名称已被使用,则会返回 NULL,否则返回 mutex 的HANDLE。
可是如下代码却:
HANDLE  hMutex1 = CreateMutex(NULL, false, "MY_TEST_mutex");
HANDLE  hMutex2 = CreateMutex(NULL, false, "MY_TEST_mutex");
HANDLE  hMutex3 = CreateMutex(NULL, false, "MY_TEST_mutex");
却每次都反别返回
0x5c, 0x60, 0x64请问这是怎么回事啊?

解决方案 »

  1.   

    另外,我的系统是中文 win2000 sp3, VC6 sp5。
      

  2.   

    如果已经被使用,返回的不是NULL,调用GetLastError()来判断是否已经被使用了
      

  3.   

    如果GetLastError() == ERROR_ALREADY_EXISTS则表明已经被使用了
      

  4.   

    谢谢,但是,如 msdn 上所言:
    If the function succeeds, the return value is a handle to the mutex object. If the named mutex object existed before the function call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS. Otherwise, the caller created the mutex.三次调用 createmutex 的返回也应该是一样的啊?
      

  5.   

    如果你创建的Mutex已经被使用,而你再次调用了CreateMutex来创建一个同名的Mutex那么返回的是指向已经存在的哪个Mutex的句柄!!用GetLastError可以获得ERROR_ALREADY_EXISTS
    的通知!
      

  6.   

    但是! HANDLE  hMutex1 = CreateMutex(NULL, false, "MY_TEST_mutex");
    HANDLE  hMutex2 = CreateMutex(NULL, false, "MY_TEST_mutex");
    HANDLE  hMutex3 = CreateMutex(NULL, false, "MY_TEST_mutex");

    hMutex1 = 0x005c;
    hMutex2 = 0x0060;
    hMutex3 = 0x0064;
    照各位说法和 msdn 的说法,应该都是返回 0x005c 呀,
    我都快憋死了,找不到问题所在。
    大家可以编个例程自己试试,
      

  7.   

    通过试验发现:
    1、如果已命名mutex存在,则另外创建一个 mutex, 二者独立,Win98、Win2k 均如此
    2、如果已命名非mutex存在,则返回 false
    3、如果OpenMutex,则必须closehandle,否则无法释放mutex, 如果再重新创建 mutex 的话,仍会出现ERROR_ALREADY_EXISTS错误。
      

  8.   

    第二次调用CreateMutex的时候,返回的应该是一个副本吧
      

  9.   

    不是副本。是另外一个。
    以下代码
    HANDLE  hMutex1 = CreateMutex(NULL, false, "MY_TEST_mutex");
    HANDLE  hMutex2 = CreateMutex(NULL, false, "MY_TEST_mutex");
    CloseMutex(hMutex1);
    HANDLE  hMutex3 = CreateMutex(NULL, false, "MY_TEST_mutex");
    if( GetLastError()==ERROR_ALREADY_EXISTS)
        AfxMessageBox("already exist!");
    如果是副本,那么消息框不应出现,但是,试验是出现的。
      

  10.   

    我的理解应该是:CreateMutex,OpenMutex返回的仅仅MUTEX对象的类似于副本的,每次调用这些函数,在WINDOW核心都对MUTEX对象作了一个计数器,调用CLOSEHANDLE的时候,计数器减一,如果为0的时候,则销毁该MUTEX对象,因此,上面的代码中,由于两次调用CreaetMutex,尽管调了一次CloseMutex,但是该mutex对象还有被使用,所以没有被销毁,再次调用createmutex的时候,会返回error_already_exists的错误
      

  11.   


    我觉得应该是同一个,就是说,同一个Windows的核心对象,可以有不同的句柄。
      

  12.   

    猜想应该“信誉”的说法对:同一个Windows的核心对象,可以有不同的句柄。
    但是,其表现和多个对象又有什么区别呢?我可以认为根本就是多个对象,只不过拥有同一名字。
    msdn 上的说法实在是不太恰当。
    我所知道的,窗口对象的handle 是唯一的,其他的process是唯一的, HMODULE因为是相对于进程的,所以也是唯一的。
    而 event 的情况和 mutex 类似。
      

  13.   

    hdxy(混沌小妖)  你的理解是对的。
      

  14.   

    建议 你 好好地把 MSDN 中的 CreateMutex 函数,说明  看一看。多看几遍。
      

  15.   

    对,mutex是一个Windows的核心对象,可以给不同的进程使用,它的实体当然不可能在0x005c,0x0060这种你的单个进程的地址空间。可以理解为同一个核心对象的不同句柄,你可以通过这个句柄对同一个Windows核心对象进行操作。
      

  16.   

    如果是多个对象,你怎么通过他来同步不同的线程甚至进程?肯定是同一个Windows的核心对象的不同句柄。
      

  17.   

    WIN2K是支持系统调用重入的,所以应该是不同的MUTEX,
    但是在WIN9X下没有解决,所以可能有问题
      

  18.   

    lpName 
    [in] Pointer to a null-terminated string specifying the name of the mutex object. The name is limited to MAX_PATH characters. Name comparison is case sensitive. //重点
    If lpName matches the name of an existing named mutex object, this function requests the MUTEX_ALL_ACCESS access right. In this case, the bInitialOwner 
    //parameter is ignored because it has already been set by the creating process. If the lpMutexAttributes parameter is not NULL, it determines whether the handle can be inherited, but its security-descriptor member is ignored.If lpName is NULL, the mutex object is created without a name.//重点, 这里没有说 the name of existing mutex
    If lpName matches the name of an existing event, semaphore, waitable timer, job, or file-mapping object, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same name space.
    //
      

  19.   

    抱歉,我来总结一下。1、如果已命名mutex存在,则另外创建一个 mutex, 二者独立,Win98、Win2k 均如此//重点
    If lpName matches the name of an existing named mutex object, this function requests the MUTEX_ALL_ACCESS access right. In this case, the bInitialOwner 
    //
    如果你设置了 MUTEX_ALL_ACCESS,就是有了一个了,这个时候,CreateMutex 就是 打开,而不是 创建。
    2、如果已命名非mutex存在,则返回 false//重点, 这里没有说 the name of existing mutex
    If lpName matches the name of an existing event, semaphore, waitable timer, job, or file-mapping object, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same name space.
    //
    这个对应你的 2。
      

  20.   

    3、如果OpenMutex,则必须closehandle,否则无法释放mutex, 如果再重新创建 mutex 的话,仍会出现ERROR_ALREADY_EXISTS错误。释放mutex 必须是 记数为 0时,才释放。//这个 重新创建,是怎么回事?
      

  21.   

    大哥们不对啊,         
    HANDLE  hMutex1 = CreateMutex(NULL, false, "MY_TEST_mutex");
    HANDLE  hMutex2 = CreateMutex(NULL, false, "MY_TEST_mutex");
    ReleaseMutex(hMutex1);
    ReleaseMutex(hMutex2);
    HANDLE  hMutex3 = CreateMutex(NULL, false, "MY_TEST_mutex");
    if( GetLastError()==ERROR_ALREADY_EXISTS)
    AfxMessageBox("already exist!");
    还是会执行AfxMessageBox("already exist!");好像没有CloseMutex()这个函数
    我的想法是这样的,你用ReleaseMutex(hMutex1);只能释放hMutex1这个变量,而它所标识的资源仍然还在,所以无论你ReleaseMutex多少次,if( GetLastError()==ERROR_ALREADY_EXISTS)都会成立,除非资源被释放,即进程或线程退出,或者关闭了使用该资源的句柄。

      

  22.   

    to yaoha2003(爱老婆更爱键盘!) 兄弟:
      是 CloseHandle,没有 CloseMutex 函数。
      

  23.   

    我想我似乎明白了:
    的确,只有一个内核对象。
    我一直纳闷对于 createMutex、OpenMutex,
    多个进程中有不同的handle 可以理解,为何同一进程中会返回不同handle
    其实很 sillily 的, mutex 是同步线程的,而非同步进程的,
    而进程的地址空间是统一的,这要求当同一进程中的不同线程在存取同一mutex时,必须有不同的 ID, 也就是 handle 了。
    这样看,便一切都解决了。
    当一个命名 mutex 已经存在时, createMutex 和 OpenMutex 是没有太多区别的。
    这时,两个函数都是一方面是增加一个全新的进程内的handle到内核对象的映射,一方面是在内核对象的引用计数加一;
    另外, CloseHandle 一方面是释放进程内的handle资源,一方面是在内核对象的引用计数减一。