最近寫一程序,誤用了Mutex的功能,錯把Mutex當Event用了。
【Mutex】
使用Mutex的主要函數:CreateMutex、ReleaseMutex、OpenMutex、WaitForSingleObject、WaitForMultipleObjects。
CreateMutex:其中第二個參數是表示當前線程擁有權。
TRUE:創建線程獲得初始所有權的互斥對象(即信號已被當前線程獲得,沒有釋放前其它線程不能獲得。如果當前線程調用了WaitForSingleObject函數,則釋放次數等於調用次數加1)。
FALSE:創建線程沒有獲得互斥對象的所有權。也就是自由爭取,看誰先Wait到。
不管怎么樣,MUtex的釋放規則是:誰擁有誰釋放,還有在線程結束時,線程所獲得的Mutex自動釋放;當然還可以使用命名Mutex做唯一性驗證,這個在整個windows生存期下有效。
【Event】
與Mutex不一樣,Event是任何時候都是可以操作的,而且沒有同調用多次WaitForSingleObject和同時釋放多次一說。它的主要操作函數有:CreateEvent、SetEvent、WaitForSingleObject。
CreateEvent參數說明。
第二個參數表示調用WaitForSingleObject后手動(TRUE)/自動(FALSE)為無信號狀態。
第三個參數表示初始狀態為有(TRUE)/無(FALSE)信號。
Event的獲得是通過一個隊列去排隊獲得的,SetEvent沒有限制使用,在任何可以調用的地方都可以調用。
Mutex,的互斥是以線程為基本單位,而Event是以代碼段為基本單位。所以在兩者的使用上有着不同的功能用途。
【測試代碼】
// Mutex_release.cpp : 定義控制台應用程序的入口點。 // // #include "stdafx.h" #include "iostream" #include "windows.h" using namespace std; DWORD WINAPI ThreadProc1(LPVOID lpParam); DWORD WINAPI ThreadProc2(LPVOID lpParam); HANDLE hEvent = NULL; HANDLE hThread1 = NULL; HANDLE hThread2 = NULL; int main(int argc,char *args[]) { hEvent = CreateEvent(NULL,FALSE,FALSE,NULL); // 使用 *重置為無信號狀態,初始化時*信號狀態 // hEvent = CreateMutex(NULL, FALSE, NULL); // FALSE: 創建線程沒有獲得互斥對象的所有權 TRUE: 創建線程獲得初始所有權的互斥對象 hThread1 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc1,NULL,0,NULL); Sleep(200); hThread2 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc2,NULL,0,NULL); Sleep(200); if (NULL == hThread1 || NULL == hThread2) { cout <<"create thread fail!"; }//DWORD dReturn = WaitForSingleObject(hEvent,INFINITE); //cout<< dReturn << endl; //ReleaseMutex(hEvent); //ReleaseMutex(hEvent); while(1){ Sleep(100); // ReleaseMutex(hEvent); SetEvent(hEvent); } return 0; } DWORD WINAPI ThreadProc1(LPVOID lpParam) { cout <<"in thread1@!"<<endl; DWORD dReturn = WaitForSingleObject(hEvent,INFINITE); if (WAIT_OBJECT_0 == dReturn) { cout <<"thread1 signaled ! "<<endl; } dReturn = WaitForSingleObject(hEvent,INFINITE); if (WAIT_OBJECT_0 == dReturn) { cout <<"thread1 signaled*&* ! "<<endl; } cout <<"in thread1 --signal"<<endl; //SetEvent(hEvent); //ReleaseMutex(hEvent); //ReleaseMutex(hEvent); while(1){ Sleep(100); } return 0; } DWORD WINAPI ThreadProc2(LPVOID lpParam) { cout <<"in thread2@!"<<endl; DWORD dReturn = WaitForSingleObject(hEvent,INFINITE); if (WAIT_OBJECT_0 == dReturn) { cout <<"thread2 signaled ! "<<endl; } cout <<"in thread2--signal"<<endl; //SetEvent(hEvent); //SetEvent(hEvent); //ReleaseMutex(hEvent); while(1){ Sleep(100); } return 0; } //int _tmain(int argc, _TCHAR* argv[]) //{ // //// HANDLE m_hMutex = CreateEvent(NULL,FALSE,TRUE,NULL);// 檢查錯誤代碼 // HANDLE m_hMutex = CreateMutex(NULL, TRUE, NULL); // if(m_hMutex == NULL) // { // printf("create no!\n"); // return -1; // } // // printf("create yes!\n"); // WaitForSingleObject(m_hMutex, INFINITE); // printf("wait yes\n"); // // //SetEvent(m_hMutex); // //SetEvent(m_hMutex); // //SetEvent(m_hMutex); // // //ReleaseMutex(m_hMutex); // //ReleaseMutex(m_hMutex); // //ReleaseMutex(m_hMutex); // // WaitForSingleObject(m_hMutex, INFINITE); // printf("wait yes 2\n"); // WaitForSingleObject(m_hMutex, INFINITE); // printf("wait yes 3\n"); // WaitForSingleObject(m_hMutex, INFINITE); // printf("wait yes 4\n"); // WaitForSingleObject(m_hMutex, INFINITE); // printf("wait yes 5\n"); // WaitForSingleObject(m_hMutex, INFINITE); // printf("wait yes 6\n"); // WaitForSingleObject(m_hMutex, INFINITE); // printf("wait yes 7\n"); // return 0; //}