MSDN中关于ReleaseMutex函数有这样一句话:Res
The ReleaseMutex function fails if the calling thread does not own the mutex object.如果调用ReleaseMutex的线程对mutex没有拥有权的话,函数调用将失败.
那么什么情况下能够拥有mutex的所有权呢,下面说调用wait 函数和创建mutex即可,调用ReleaseMutex是释放所有权.我的问题就这样产生了....
//-------------------------------demo.h----------------------------------------------class CDemo
{
public:
    CDemo(void);
    ~CDemo(void);
    void Lock();
    void UnLock();
private:
    HANDLE      m_hread;    
};//-------------------------------demo.cpp----------------------------------------------#include "StdAfx.h"
#include "Demo.h"CDemo::CDemo(void)
:m_nread(0)
{
    m_hread    = CreateMutex(NULL, FALSE, NULL);
}CDemo::~CDemo(void)
{
    CloseHandle(m_hread);
}void CDemo::Lock(DWORD n)
{    
    WaitForSingleObject(m_hread, INFINITE);
    AfxTrace(TEXT("LOCK %d\r\n"), ::GetCurrentThreadId());
}void CDemo::UnLock(DWORD n)

    AfxTrace(TEXT("Release %d\r\n"), ::GetCurrentThreadId());
    if (!ReleaseMutex(m_hread))
    {
        TRACE("FAILED TO RELEASE\r\n");
    }
}//-------------------------------test.cpp---------------------------------------------static UINT WINAPI LockThread(void *);
static UINT WINAPI UnLockThread(void *);UINT CTest::LockThread(void *p)
{
    CDemo *pP = static_cast<CDemo*>(p);
    pP->Lock();
}UINT CTest::UnLockThread(void *p)
{
   CDemo* pP = static_cast<CDemo*>(p);
   pP->UnLock();
}CTest::OnBnTest()
{
    const int THREAD_COUNT;
    HANDLE hThreads[THREAD_COUNT + 1];
    
    //...
    
    HANDLE hThread1 = (HANDLE)_beginthreadex(NULL, 0, &LockThread, &demo, 0, NULL);
    HANDLE hThread2 = (HANDLE)_beginthreadex(NULL, 0, &UnLockThread, &demo, 0, NULL);}
函数执行没有,OUTPUT栏中没有找到 FAILED TO RELEASE, 这说明释放成功了,为什么?????是MSDN上面说的不对?如果它是对的,为什么这个地方可以释放成功?锁和解锁分别属于不同的线程啊.

解决方案 »

  1.   

    LockThread()和UnLockThread()里面的pP是不同的吧,m_hread不是static,这样就是两个线程拥有两个不同的mutex了
      

  2.   

    是相同的,对同一个object做操作的.
      

  3.   

    你这里有2个问题:
    1. 主线程退出后,2个子线程还没来的及运行就退出
    2. m_hread    = CreateMutex(NULL, FALSE, NULL); //互斥对象开始时不发出通知信号
       wait func是指有线程对该内核对象请求资源后(如WaitForSingleObject、SignalObjectAndWait等详见csdn),该内核对象的状态由未通知状态nonsignaled置为已通知状态signaled
    我改了下你的代码,如下,可提示出“FAILED TO RELEASE"
    //-------------------------------demo.h----------------------------------------------#include <windows.h>
    #include <stdio.h>class CDemo
    {
    public:
        CDemo(void);
        ~CDemo(void);
        void Lock();
        void UnLock();
    private:
        HANDLE      m_hread;    
    };CDemo::CDemo(void)
    :m_hread(0)
    {
        m_hread    = CreateMutex(NULL, FALSE, NULL);
    }CDemo::~CDemo(void)
    {
        CloseHandle(m_hread);
    }void CDemo::Lock()
    {    
        WaitForSingleObject(m_hread, INFINITE);
        printf(TEXT("LOCK %d\r\n"), ::GetCurrentThreadId());
    }void CDemo::UnLock()

        printf(TEXT("Release %d\r\n"), ::GetCurrentThreadId());
        if (!ReleaseMutex(m_hread))
        {
            printf("FAILED TO RELEASE\r\n");
        }
    }//-------------------------------console.cpp----------------------------------------------
    #include <windows.h>
    #include <process.h>
    #include "deamon.h"HANDLE g_Event;UINT WINAPI LockThread(PVOID pvParam)
    {
    WaitForSingleObject(g_Event,INFINITE);
        CDemo *pP = static_cast<CDemo*>(pvParam);
        pP->Lock();
    return 0;
    }UINT WINAPI UnLockThread(PVOID pvParam)
    {
       WaitForSingleObject(g_Event,INFINITE);
       CDemo* pP = static_cast<CDemo*>(pvParam);
       pP->UnLock();
       return 0;
    }int  main(int argc , char* argv[] )
    {
        HANDLE hThread[2];
        CDemo demo;
        //...
        g_Event = CreateEvent(NULL,TRUE,FALSE,NULL);
        DWORD dwThreadID;
        hThread[1] = (HANDLE)_beginthreadex(NULL, 0, UnLockThread, &demo, 0, (unsigned *)&dwThreadID);
        SetEvent(g_Event);
        WaitForSingleObject(hThread[1],INFINITE);
        hThread[0] = (HANDLE)_beginthreadex(NULL, 0, LockThread, &demo, 0, (unsigned *)&dwThreadID);    WaitForMultipleObjects(2, hThread, TRUE, INFINITE);
        CloseHandle(hThread[0]);
        CloseHandle(hThread[1]);
        CloseHandle(g_Event);
        getchar();
        return 0;
    }
      

  4.   

    我没有把代码贴完整,你说的那个主线程退出子线程没有运行对我来说并不存在.你的代码测试过吗?确实能打印出 FAILED TO RELEASE 来吗?我在XP SP2 + VS2005没有这个输出.
      

  5.   

    我昨晚已经测试过,记得用控制台选项编译(/subsystem:console),you can try again.
      

  6.   

    楼上的,我对你无语了,你调换了线程的执行次序,让UnLock先执行,这当然会失败了.开始我是没有认真看,现在我是认真看而且还执行了你的代码.我想的是Lock在前,UnLock在后,你竟然把顺序给我反过来了.我不是要弄出RELEASE FAILED, 我是要搞清楚为什么没有拥有mutex的线程调用ReleaseMutex为什么会失败!!!!
    谢谢你的回贴,虽然你没有搞懂我发贴的本意.
      

  7.   

    我不是要弄出RELEASE FAILED, 我是要搞清楚为什么没有拥有mutex的线程调用ReleaseMutex为什么不会失败!!!!刚才回贴漏了一个字.
      

  8.   

    我想道理是一样的
    case 1:
    Thread1线程执行完毕后,该线程终止运行,系统将自动将互斥对象的ID置为0,该Mutex为signaled状态
    Thread1执行完毕后,Thread2执行,ReleaseMutex返回成功
    case 2:
    Thread1线程执行未结束时,Thread2开始执行,ReleaseMutex返回必然是失败之所以让Thread2先运行,是为了测试Thread2在Thread1 wait之前通过ReleaseMutex来调用nonsignaled状态的内核对象,返回也是失败
    不知道我说的是否清楚?
      

  9.   

    我估计你的问题是case 1,但是case 3你也要考虑,至少你的代码没有反映出来