原文鏈接:http://www.shnenglu.com/wangjt/archive/2008/01/30/42235.html
Mutex是互斥體的意思,當一個線程持有一個Mutex時,其它線程申請持有同一個Mutex會被阻塞,因此可以通過Mutex來保證對某一資源的互斥訪問(即同一時間最多只有一個線程訪問)。
調用CreateMutex可以創(chuàng)建或打開一個Mutex對象,其原型如下
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes,
BOOL bInitialOwner,
LPCTSTR lpName
);
其中參數(shù)lpMutexAttributes用來設定Mutex對象的安全描述符和是否允許子進程繼承句柄。bInitialOwner表明是否將Mutex的持有者設置為調用線程。lpName參數(shù)設置Mutex的名字,該名字區(qū)分大小寫并不能包含"\",最大長度為MAX_PATH,可設置為NULL表明該Mutex為匿名對象。
如果調用成功,則返回Mutex的句柄,否則返回NULL,如果lpName不為NULL且調用前同名的Mutex已被創(chuàng)建,則返回同名Mutex的句柄,此時調用GetLastError將返回ERROR_ALREADY_EXISTS,參數(shù)bInitialOwner將被忽略。
還可以調用OpenMutex打開創(chuàng)建的非匿名Mutex,原型如下
HANDLE OpenMutex(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCTSTR lpName
);
在成功創(chuàng)建或打開Mutex后,可以使用wait functions來等待并獲取Mutex的持有權。
下面的例子用來通過Mutex對象控制某一應用程序只運行一次
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
HANDLE hMutex = CreateMutex(NULL, FALSE, "Mutex_Only_One_Instance_Allowed");
if (NULL == hMutex)
{
Error("Create mutex error.");
return -1;
}
DWORD dw = WaitForSingleObject(hMutex, 0);
if (WAIT_FAILED == dw)
{
Error("Wait for mutex error.");
CloseHandle(hMutex); // 釋放句柄,當指向同一系統(tǒng)對象的所有句柄釋放后,該對象將被刪除。
return -1;
}
else if (WAIT_TIMEOUT == dw)
{
// 另外一個實例正在運行
CloseHandle(hMutex);
return 1;
}
// 沒有其它實例在運行,本實例將繼續(xù)運行
// 在此實現(xiàn)必要的功能性代碼,如創(chuàng)建窗口,進入消息循環(huán)
// ...............
ReleaseMutex(hMutex); // 釋放hMutex的持有權,注意這并不等同于刪除Mutex對象
CloseHandle(hMutex);
return 0;
}
其中WaitForSingleObject是等待特定對象發(fā)出信號(signaled),而Mutex對象在沒有任何線程持有時會發(fā)出信號。