Mutex與Event控制互斥事件的使用詳解


  最近寫一程序,誤用了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;
//}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM