问题描述:
      多线程环境下,某个线程A先判断是否已经有线程在执行线程函数ThreadProc(),如果有,线程A不等待,直接返回,如果没有,则线程A创建新的线程执行该线程函数。
代码如下:
  DWORD WINAPI _ThreadProc(LPVOID lparam)
{
HANDLE mutex = CreateMutex(NULL,TRUE,"BUSY");
if(::GetLastError() == ERROR_ALREADY_EXISTS)
{
        return 0;
}
        .........        BOOL t = ::ReleaseMutex(mutex);
return 0;
}   其他线程中的代码:
        g_pConn = ::CreateThread(NULL,NULL,_ThreadProc,NULL,0,&g_connThreadID);
   现在这样做第一个线程到达时,可以正常的创建ThreadProc,创建mutex,在ReleaseMutex之前,其他线程到达时,会在创建mutex时发生已经存在的错误,然后直接返回,这是我期望的效果。但问题是即使线程函数中ReleaseMutex后,其他线程到达后在创建mutex时,还是会产生已经存在的错误。总结一句话就是,这个线程函数只能被调用一次,其后
mutex对象好像就释放不掉了。
   我也尝试将mutex作为全局变量,然后在ThreadProc外判断mutex对象是否已经创建,即类似如下的代码:
 DWORD WINAPI _ThreadProc(LPVOID lparam)
{
        .........        BOOL t = ::ReleaseMutex(g_mutex);
return 0;
}
  其他线程中的代码:
       g_Mutex = ::CreateMutex(NULL,TRUE,"BUSY");
      if(::GetLastError() == ERROR_ALREADY_EXISTS)
      {
         return DB_DISCONNECT_ERROR;
      }
        g_pConn = ::CreateThread(NULL,NULL,_ThreadProc,NULL,0,&g_connThreadID);
但这样会在ReleaseMutex时出错,提示288,即企图释放并非呼叫方所拥有的多用户终端运行程序。 
将mutex句柄作为线程参数传进去也是一样。到底该如何控制线程函数同一时刻只能被一个线程执行,而其他线程不等待这样的功能呢。
   

解决方案 »

  1.   

    建议仔细看下MSDN中有关mutex的概念, 然后你就能理解下面代码是什么意思了:
    // 全局mutex
    HANDLE g_Mutex;....g_Mutex = CreateMutex(NULL, FALSE, "BUSY");...// 线程函数
    DWORD   WINAPI   _ThreadProc(LPVOID   lparam) 
    {
        if( WaitForSingleObject(g_Mutex, 0) == WAIT_TIMEOUT ) // 其他线程已启动
        {
            return 0;
        }
        ....
        ReleaseMutex(g_Mutex);
        return 0;
    }使用局部mutex也一样
    DWORD   WINAPI   _ThreadProc(LPVOID   lparam) 
    {
        HANDLE mutex = CreateMutex(NULL, FALSE, "BUSY");
        if( WaitForSingleObject(mutex, 0) == WAIT_TIMEOUT )
        {
            CloseHandle(mutex);
            return 0;
        }
        ....
        ReleaseMutex(mutex);
        CloseHandle(mutex);          
    }
      

  2.   

    to Idle_:对于全局变量g_Mutex,为什么不能在_ThreadProc()线程外执行判断WaitForSingleObject(),如果结果为真则不创建新的线程,这样我就不需要重复的创建新线程乐
    HANDLE   g_Mutex; .... g_Mutex   =   CreateMutex(NULL,   FALSE,   "BUSY "); 
    if(   WaitForSingleObject(g_Mutex,   0)   ==   WAIT_TIMEOUT   )   //   其他线程已启动 

        return   0; 
    }
     //   线程函数 
    DWORD       WINAPI       _ThreadProc(LPVOID       lparam)   

             .... 
            ReleaseMutex(g_Mutex); 
            return   0; 
      

  3.   

    上面有误!
    对于全局变量g_Mutex,为什么不能在_ThreadProc()线程外执行判断WaitForSingleObject(),如果结果为真则不创建新的线程,这样我就不需要重复的创建新线程乐 
    HANDLE       g_Mutex;   ....   g_Mutex       =       CreateMutex(NULL,       FALSE,       "BUSY   ");   
    if(::GetLastError() == ERROR_ALREADY_EXISTS)
    {
               return DB_DISCONNECT_ERROR;
    }  //       线程函数   
    DWORD               WINAPI               _ThreadProc(LPVOID               lparam)       
    {   
          if(       WaitForSingleObject(g_Mutex,       0)       ==       WAIT_TIMEOUT       )       //       其他线程已启动   
         {   
            return       0;   
         }          ....   
         ReleaseMutex(g_Mutex);  
         CloseHandle(g_Mutex) 
         return       0;   
    }  
      

  4.   

    不知道我理解的对不对,WaitForSingleObject的作用获得互斥变量的拥有权,所以在线程外创建CreateMutex的时候需将第二个参数设为False.
    感觉还是晕晕乎乎的,再好好看看msdn去