• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • windows多線程(五) 互斥量 Mutex

    一、互斥量

    互斥量是windows的一個內核對象,互斥量與關鍵段的作用相似,可以用來確保全局資源的互斥訪問。并且互斥量可以用在不同的進程中的線程互斥訪問全局資源。

    二、相關函數說明

    使用互斥量Mutex主要用到以下四個函數,下面將介紹這四個函數。

    (一) 創建互斥量

    1. 函數原型
    
    HANDLE CreateMutex(
    
      LPSECURITY_ATTRIBUTE  SlpMutexAttributes,
    
      BOOL   bInitialOwner,     
    
      LPCTSTR    lpName
    
    );
    
    2.參數說明
    • 第一個參數表示安全控制,一般直接傳入NULL。

    • 第二個參數用來確定互斥量的初始擁有者。如果傳入TRUE表示互斥量對象內部會記錄創建它的線程的線程ID號并將遞歸計數設置為1,由于該線程ID非零,所以互斥量處于未觸發狀態。如果傳入FALSE,那么互斥量對象內部的線程ID號將設置為NULL,遞歸計數設置為0,這意味互斥量不為任何線程占用,處于觸發狀態。

    • 第三個參數用來設置互斥量的名稱,在多個進程中的線程就是通過名稱來確保它們訪問的是同一個互斥量。

    • 函數返回值:成功返回一個表示互斥量的句柄,失敗返回NULL。

    (二) 打開互斥量

    1. 函數原型
    
    HANDLE OpenMutex(
    
     DWORD   dwDesiredAccess,
    
     BOOL   bInheritHandle,
    
     LPCTSTR   lpName    
    
    );
    
    2.參數說明
    • 第一個參數表示
    • 權限,對互斥量一般傳入MUTEX_ALL_ACCESS。

    • 第二個參數表示互斥量句柄繼承性,一般傳入TRUE即可。

    • 第三個參數表示名稱。某一個進程中的線程創建互斥量后,其它進程中的線程就可以通過這個函數來找到這個互斥量。

    • 函數返回值:成功返回一個表示互斥量的句柄,失敗返回NULL。

    (三) 觸發互斥量

    1. 函數原型
    BOOLReleaseMutex (HANDLEhMutex)
    2.參數說明

    傳入參數為從創建或打開互斥量時返回的句柄。 訪問互斥資源前應該要調用等待函數,結束訪問時就要調用ReleaseMutex()來表示自己已經結束訪問,其它線程可以開始訪問了。

    (四) 釋放互斥量

    由于互斥量是一個內核對象,釋放時直接調用 CloseHandle(HANDLE hObject) 函數就可以了,所有內核對象都是這樣釋放。

    三、實例

    1.創建并使用互斥量

    
    #include <stdio.h>
    #include <windows.h>
    
    const unsigned int THREAD_NUM = 15;
    unsigned int g_Count = 0;
    HANDLE g_Mutex;  //聲明一個內核對象
    DWORD WINAPI  ThreadFunc(LPVOID);
    
    int main()
    {
        g_Mutex = CreateMutex(NULL,false,NULL);  // 創建互斥量,初始化為觸發狀態
        HANDLE hThread[THREAD_NUM];
        for (int i = 0; i < THREAD_NUM; i++)
        {
            hThread[i] = CreateThread(NULL, 0, ThreadFunc, &i, 0, NULL); // 創建線程    
        }
    
        WaitForMultipleObjects(THREAD_NUM, hThread, true, INFINITE);    //一直等待,直到所有子線程全部返回
    
        printf(" 總共 %d 個線程給 g_Count 的值加1,現在 g_Count = %d \n\n", THREAD_NUM, g_Count);
    
        CloseHandle(g_Mutex);  //釋放互斥量
        return 0;
    }
    
    DWORD WINAPI  ThreadFunc(LPVOID p)
    {
        int ThreadNum = *(int *)p;
    
        WaitForSingleObject(g_Mutex, INFINITE);  //等待互斥量觸發
    
        printf(" 第 %d 個線程給全局資源 g_Count 的值加1,現在 g_Count = %d\n", ThreadNum, ++g_Count);
    
        ReleaseMutex(g_Mutex);  // 觸發互斥量
    
        return 0;
    }
    

    程序運行結果如下圖:
    825979-20180416225320419-562239355.png

    上面的程序中使用互斥量實現了對全局資源的互斥訪問,但是并沒有按照我們所預料順序每個線程依次給 g_Count 加一。這說明使用互斥量只是實現了全局資源的互斥訪問,并沒有實現線程的同步,有關線程同步,會在接下來的文章中學習。

    2.打開其他程序創建的互斥量

    創建互斥量的程序(CreateMutex.c):

    
    #include <stdio.h>
    #include <windows.h>
    
    const char MutexName[] = "MyMutex"; //互斥量名字
    
    int main()
    {
        HANDLE hMutex = CreateMutex(NULL, TRUE, MutexName); //創建互斥量并初始化為未觸發狀態
        printf("互斥量已經創建,按任意鍵觸發\n");
        getch();
    
        ReleaseMutex(hMutex); // 觸發互斥量
        printf("互斥量已經被觸發\n");
        CloseHandle(hMutex);
        return 0;
    }
    

    使用互斥量的程序(OpenMutex.c):

    
    #include <stdio.h>
    #include <windows.h>
    
    const char MutexName[] = "MyMutex"; //互斥量名字
    
    int main()
    {
        HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, TRUE, MutexName); //打開互斥量
        
        if (NULL != hMutex)
        {
            printf("打開互斥量成功,等待互斥量被觸發\n");
            WaitForSingleObject(hMutex, INFINITE); // 等待互斥量被觸發
            printf("互斥量已經被觸發\n");
        }
        else
        {
            printf("打開互斥量失敗。\n");
        }
        
        
        CloseHandle(hMutex);
        return 0;
    }
    
    
    

    先運行第一個程序創建互斥量,輸出 互斥量已經創建,按任意鍵觸發 后,運行第二個程序,打開互斥量,打開互斥量后,在第一個程序窗口按任意鍵觸發互斥量,兩個窗口都會輸出互斥量已經被觸發。運行結果如下圖:

    825979-20180416231819299-62986395.png

    關于互斥量的使用就先介紹到這兒,其實前面的關鍵段介紹和互斥量都還有很多內容沒寫到,我打算單獨寫一篇來分析他們兩個的區別和共同點,這里就先不介紹了。

    版權聲明:本文為weixin_30617561原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/weixin_30617561/article/details/99000212

    智能推薦

    C++11并發與多線程筆記(12) windows臨界區、其他各種mutex互斥量

    第十二節 windows臨界區、其他各種mutex互斥量 一和二、windows臨界區 Windows臨界區,同一個線程是可以重復進入的,但是進入的次數與離開的次數必須相等。 C++互斥量則不允許同一個線程重復加鎖。 windows臨界區是在windows編程中的內容,了解一下即可,效果幾乎可以等同于c++11的mutex 包含#include <windows.h> windows中...

    多核多線程自旋鎖spinlock 與互斥量mutex性能分析

    多核多線程 自旋鎖(spinlock )與 互斥量(mutex) mutex方式:(sleep-wait) 從實現原理上來講,Mutex屬于sleep-waiting類型的鎖。例如在一個雙核的機器上有兩個線程(線程A和線程B),它們分別運行在Core0和Core1上。假設線程A想要通過pthread_mutex_lock操作去得到一個臨界區的鎖,而此時這個鎖正被線版程B所持有,那么線程A就會被阻塞...

    【線程同步與互斥】互斥鎖(mutex)

    在多線程訪問共享數據的時候可能會發生沖突,例如: 我們會觀察到: 數據完全亂套了,沒有得到預期的20。 和這個類似的還有一個有趣的例子: 這個例子運行以后沒有沖突,這是為什么呢?!在和同學討論并經過自己動手實踐以后證實,其實只要把循環次數增加,比如增加到10000000,還是會觀察到沖突的,如下圖: 也就是說,當數據量小的時候,執行速度較快,給人的錯覺是“順序”執行的,但是...

    linux系統編程 互斥量函數(pthread_mutex) 線程加鎖

    線程同步測試 先看一個測試程序 結果如下,兩個主線程打印順序發生錯亂 加鎖 結果如下,有序打印 死鎖現象 兩次加鎖會讓程序死鎖,阻塞等待...

    【Linux】深入理解線程(線程同步、互斥量mutex、死鎖、讀寫鎖、條件變量、信號量)

    一、同步概念        1、線程同步:             同步即協同步調,按預定的先后次序運行。             線程同步,只一個線程發出某一功能調用時,在沒有得到結果之前,該調用不返回。同時,其他線程為保證數據一致性,不...

    猜你喜歡

    VC++中多線程學習(MFC多線程)三(線程同步包含:原子互鎖、關鍵代碼段、互斥器Mutex、Semaphores(信號量)、Event Objects(事件))

    目錄 ???????????? 線程同步的必要性: 2.解決同步問題的方法 2.1原子互鎖家族函數 2.2Critical Sections(關鍵代碼段、關鍵區域、臨界區域) 2.3 互斥器Mutex 2.4 Semaphores(信號量) 2.5 Event Objects(事件) 線程同步的必要性: 我們知道操作系統的執行最小單位是線程,而一個進程包含了很多的線程,現在已經實現了 真正的并行,...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    精品国产乱码久久久久久蜜桃不卡