Windows C++ 四種線程同步的創建與使用方式

 

1.互斥量

   /*
    *用於保護全局變量、硬件端口、管道識別碼、窗口客戶區
    *多個線程共享資源時,優先考慮互斥量
    *Mutex 可以跨進程使用,所以其名稱對整個系統而言是全局的
    *param1:安全特徵,可以指定,也可以不填
    *param2:線程所有權,設置爲TRUE,調用方立即獲得互斥量所有權
    *param3:互斥量名稱必須指定
    */

此處若把參數2設置爲TRUE,即創建線程互斥量,當前線程即獲取該互斥量,需在同一個線程釋放

h_Mutex = CreateMutex(NULL, FALSE, "mutex");

    /*
    *爲現有的已經存在的互斥量對象創建一個新句柄
    *param1:請求訪問方式 安全特徵
    *        MUTEX_ALL_ACCESS    請求對互斥體的完全訪問
    *        MUTEX_MODIFY_STATE    允許使用 ReleaseMutex 函數
    *        SYNCHRONIZE            允許互斥體對象同步使用
    *
    *param2:如希望子進程能夠繼承句柄,則爲TRUE
    *param3:要打開對象的名字
    *互斥量不存在返回失敗ERROR_FILE_NOT_FOUND 必須釋放互斥量ReleaseMutex
    */

HANDLE ret = OpenMutex(MUTEX_ALL_ACCESS, TRUE, "mutex");

等待互斥量

WaitForSingleObject(h_Mutex, INFINITE);//等待互斥量

釋放互斥量

BOOL ret = ReleaseMutex(h_Mutex);

2.信號量

    /*
    *用於保護全局變量、硬件端口、管道識別碼、窗口客戶區
    *多個線程共享資源時,優先考慮互斥量
    *Semaphores 可以跨進程使用,所以其名稱對整個系統而言是全局的
    *param1:安全特徵,可以指定,也可以不填 NULL默認安全方式
    *        MUTEX_ALL_ACCESS    請求對互斥體的完全訪問
    *        MUTEX_MODIFY_STATE    允許使用 ReleaseMutex 函數
    *        SYNCHRONIZE            允許互斥體對象同步使用
    *param2:初始數目以確定信號量初始觸發狀態,設置爲0,爲未觸發狀態,如果當前資源計數等於0,那麼信號量處於未觸發狀態;那麼系統會讓調用線程進入等待狀態
    *param3:可同時持有信號量所有權的最多線程對象數目
    *param4:必須提供信號量名
    */

創建信號量

h_Semaphore = CreateSemaphore(NULL, 0, 1, "semaphore");

等待信號量

WaitForSingleObject(h_Semaphore, INFINITE);//等待互斥量

釋放信號量

BOOL ret = ReleaseSemaphore(h_Semaphore, 1, NULL);

 

3.事件對象

    /*
    *param1:安全特徵,可以指定,也可以不填 NULL默認安全方式.確定返回的句柄是否可被子進程繼承,是NULL,此句柄不能被繼承
    *param2:用於確定事件對象,TRUE代表必須把ResetEvent中事件對象設置爲未觸發狀態.(TRUE)必須使用ResetEvent()手動重置爲無信號狀態
    *                      FALSE當一個等待線程被釋放時,自動重置狀態爲無信號狀態
    *param3:設置事件初始狀態,爲TRUE則表示立即設置爲觸發狀態
    *param4:必須提供事件名
    */

創建事件對象

h_Event = CreateEvent(NULL, TRUE,TRUE,"event");

將事件對象設置爲已觸發狀態

BOOL ret = SetEvent(h_Event);

將事件對象設置爲未觸發狀態

BOOL ret = ResetEvent(h_Event);

脈衝事件,將事件對象設置爲已觸發狀態,然後將其重置爲未觸發狀態,釋放特定數量的等待線程

BOOL ret = PulseEvent(h_Event);

事件對象在創建時候的四種情況分析,針對參數二和參數三

1.人工重置事件:使用手動重置爲無信號狀態,初始化時有信號狀態,調用WaitForSingleObject不會等待

CreateEvent(NULL, TRUE, TRUE, NULL)

2.人工重置事件:使用手動重置爲無信號狀態,初始化時爲無信號狀態 調用WaitForSingleObject會一直等待

CreateEvent(NULL, TRUE, FALSE, NULL);

若某個線程調用WaitForSingleObject(hEvent,INFINITE) 則會一直等待,需要先調用SetEvent()設置爲有信號狀態,才能繼續執行,否則一直在等待;ResetEvent(),要想有信號需調用SetEvent(hEvent)

3.自動重置事件:當一個等待線程被釋放時,自動重置爲無信號狀態,初始是有信號狀態,調用WaitForSingleObject不會等待

CreateEvent(NULL, FALSE, TRUE, NULL);

另一個線程若還需要等到通知,即在當前線程調用SetEvent()

4.自動重置事件:線程釋放後自動重置爲無信號狀態,初始化時爲無信號狀態

CreateEvent(NULL, FALSE, FALSE, NULL);

 

4.臨界區

   臨界區的功能與互斥量相同,同一時刻只被一個線程擁有
   運行速度更快,開銷更小
   開始臨界區對象處於未觸發狀態,被釋放後處於觸發狀態

    臨界區創建以及使用方式。
    1.先聲明臨界區對象
    2.初始化
    3.讓線程進入臨界區
    4.任務完成後,讓線程離開臨界區
    5.釋放資源

    //1
    CRITICAL_SECTION c_section;
    //2
    InitializeCriticalSection(&c_section);
    //3
    EnterCriticalSection(&c_section); //或者    TryEnterCriticalSection(&c_section);
    //4
    LeaveCriticalSection(&c_section);
    //5
    DeleteCriticalSection(&c_section);

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章