乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      秒殺多線程第七篇 經(jīng)典線程同步 互斥量Mutex

       Fredanf 2012-08-30
       

      秒殺多線程第七篇 經(jīng)典線程同步 互斥量Mutex

      分類: Windows多線程 Windows編程 15519人閱讀 評(píng)論(49) 收藏 舉報(bào)

      閱讀本篇之前推薦閱讀以下姊妹篇:

      秒殺多線程第四篇一個(gè)經(jīng)典的多線程同步問(wèn)題

      秒殺多線程第五篇經(jīng)典線程同步關(guān)鍵段CS

      秒殺多線程第六篇經(jīng)典線程同步事件Event

       

      前面介紹了關(guān)鍵段CS、事件Event經(jīng)典線程同步問(wèn)題中的使用。本篇介紹用互斥量Mutex來(lái)解決這個(gè)問(wèn)題。

      互斥量也是一個(gè)內(nèi)核對(duì)象,它用來(lái)確保一個(gè)線程獨(dú)占一個(gè)資源的訪問(wèn)?;コ饬颗c關(guān)鍵段的行為非常相似,并且互斥量可以用于不同進(jìn)程中的線程互斥訪問(wèn)資源。使用互斥量Mutex主要將用到四個(gè)函數(shù)。下面是這些函數(shù)的原型和使用說(shuō)明。

      第一個(gè) CreateMutex

      函數(shù)功能:創(chuàng)建互斥量(注意與事件Event的創(chuàng)建函數(shù)對(duì)比)

      函數(shù)原型:

      HANDLECreateMutex(

        LPSECURITY_ATTRIBUTESlpMutexAttributes,

        BOOLbInitialOwner,     

        LPCTSTRlpName

      );

      函數(shù)說(shuō)明:

      第一個(gè)參數(shù)表示安全控制,一般直接傳入NULL

      第二個(gè)參數(shù)用來(lái)確定互斥量的初始擁有者。如果傳入TRUE表示互斥量對(duì)象內(nèi)部會(huì)記錄創(chuàng)建它的線程的線程ID號(hào)并將遞歸計(jì)數(shù)設(shè)置為1,由于該線程ID非零,所以互斥量處于未觸發(fā)狀態(tài)。如果傳入FALSE,那么互斥量對(duì)象內(nèi)部的線程ID號(hào)將設(shè)置為NULL,遞歸計(jì)數(shù)設(shè)置為0,這意味互斥量不為任何線程占用,處于觸發(fā)狀態(tài)。

      第三個(gè)參數(shù)用來(lái)設(shè)置互斥量的名稱,在多個(gè)進(jìn)程中的線程就是通過(guò)名稱來(lái)確保它們?cè)L問(wèn)的是同一個(gè)互斥量。

      函數(shù)訪問(wèn)值:

      成功返回一個(gè)表示互斥量的句柄,失敗返回NULL

       

      第二個(gè)打開(kāi)互斥量

      函數(shù)原型:

      HANDLEOpenMutex(

       DWORDdwDesiredAccess,

       BOOLbInheritHandle,

       LPCTSTRlpName     //名稱

      );

      函數(shù)說(shuō)明:

      第一個(gè)參數(shù)表示訪問(wèn)權(quán)限,對(duì)互斥量一般傳入MUTEX_ALL_ACCESS。詳細(xì)解釋可以查看MSDN文檔。

      第二個(gè)參數(shù)表示互斥量句柄繼承性,一般傳入TRUE即可。

      第三個(gè)參數(shù)表示名稱。某一個(gè)進(jìn)程中的線程創(chuàng)建互斥量后,其它進(jìn)程中的線程就可以通過(guò)這個(gè)函數(shù)來(lái)找到這個(gè)互斥量。

      函數(shù)訪問(wèn)值:

      成功返回一個(gè)表示互斥量的句柄,失敗返回NULL

       

      第三個(gè)觸發(fā)互斥量

      函數(shù)原型:

      BOOLReleaseMutex (HANDLEhMutex)

      函數(shù)說(shuō)明:

      訪問(wèn)互斥資源前應(yīng)該要調(diào)用等待函數(shù),結(jié)束訪問(wèn)時(shí)就要調(diào)用ReleaseMutex()來(lái)表示自己已經(jīng)結(jié)束訪問(wèn),其它線程可以開(kāi)始訪問(wèn)了。

       

      最后一個(gè)清理互斥量

      由于互斥量是內(nèi)核對(duì)象,因此使用CloseHandle()就可以(這一點(diǎn)所有內(nèi)核對(duì)象都一樣)。

       

      接下來(lái)我們就在經(jīng)典多線程問(wèn)題用互斥量來(lái)保證主線程與子線程之間的同步,由于互斥量的使用函數(shù)類似于事件Event,所以可以仿照上一篇的實(shí)現(xiàn)來(lái)寫出代碼

      1. //經(jīng)典線程同步問(wèn)題 互斥量Mutex  
      2. #include <stdio.h>  
      3. #include <process.h>  
      4. #include <windows.h>  
      5.   
      6. long g_nNum;  
      7. unsigned int __stdcall Fun(void *pPM);  
      8. const int THREAD_NUM = 10;  
      9. //互斥量與關(guān)鍵段  
      10. HANDLE  g_hThreadParameter;  
      11. CRITICAL_SECTION g_csThreadCode;  
      12.   
      13. int main()  
      14. {  
      15.     printf("     經(jīng)典線程同步 互斥量Mutex\n");  
      16.     printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");  
      17.       
      18.     //初始化互斥量與關(guān)鍵段 第二個(gè)參數(shù)為TRUE表示互斥量為創(chuàng)建線程所有  
      19.     g_hThreadParameter = CreateMutex(NULL, FALSE, NULL);  
      20.     InitializeCriticalSection(&g_csThreadCode);  
      21.   
      22.     HANDLE  handle[THREAD_NUM];   
      23.     g_nNum = 0;   
      24.     int i = 0;  
      25.     while (i < THREAD_NUM)   
      26.     {  
      27.         handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL);  
      28.         WaitForSingleObject(g_hThreadParameter, INFINITE); //等待互斥量被觸發(fā)  
      29.         i++;  
      30.     }  
      31.     WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);  
      32.       
      33.     //銷毀互斥量和關(guān)鍵段  
      34.     CloseHandle(g_hThreadParameter);  
      35.     DeleteCriticalSection(&g_csThreadCode);  
      36.     for (i = 0; i < THREAD_NUM; i++)  
      37.         CloseHandle(handle[i]);  
      38.     return 0;  
      39. }  
      40. unsigned int __stdcall Fun(void *pPM)  
      41. {  
      42.     int nThreadNum = *(int *)pPM;  
      43.     ReleaseMutex(g_hThreadParameter);//觸發(fā)互斥量  
      44.       
      45.     Sleep(50);//some work should to do  
      46.   
      47.     EnterCriticalSection(&g_csThreadCode);  
      48.     g_nNum++;  
      49.     Sleep(0);//some work should to do  
      50.     printf("線程編號(hào)為%d  全局資源值為%d\n", nThreadNum, g_nNum);  
      51.     LeaveCriticalSection(&g_csThreadCode);  
      52.     return 0;  
      53. }  

      運(yùn)行結(jié)果如下圖:

      可以看出,與關(guān)鍵段類似,互斥量也是不能解決線程間的同步問(wèn)題。

             聯(lián)想到關(guān)鍵段會(huì)記錄線程ID即有“線程擁有權(quán)”的,而互斥量也記錄線程ID,莫非它也有“線程擁有權(quán)”這一說(shuō)法。

             答案確實(shí)如此,互斥量也是有“線程擁有權(quán)”概念的?!熬€程擁有權(quán)”在關(guān)鍵段中有詳細(xì)的說(shuō)明,這里就不再贅述了。另外由于互斥量常用于多進(jìn)程之間的線程互斥,所以它比關(guān)鍵段還多一個(gè)很有用的特性——“遺棄”情況的處理。比如有一個(gè)占用互斥量的線程在調(diào)用ReleaseMutex()觸發(fā)互斥量前就意外終止了(相當(dāng)于該互斥量被“遺棄”了),那么所有等待這個(gè)互斥量的線程是否會(huì)由于該互斥量無(wú)法被觸發(fā)而陷入一個(gè)無(wú)窮的等待過(guò)程中了?這顯然不合理。因?yàn)檎加媚硞€(gè)互斥量的線程既然終止了那足以證明它不再使用被該互斥量保護(hù)的資源,所以這些資源完全并且應(yīng)當(dāng)被其它線程來(lái)使用。因此在這種“遺棄”情況下,系統(tǒng)自動(dòng)把該互斥量?jī)?nèi)部的線程ID設(shè)置為0,并將它的遞歸計(jì)數(shù)器復(fù)置為0,表示這個(gè)互斥量被觸發(fā)了。然后系統(tǒng)將公平地選定一個(gè)等待線程來(lái)完成調(diào)度(被選中的線程的WaitForSingleObject()會(huì)返回WAIT_ABANDONED_0)。

       

      下面寫二個(gè)程序來(lái)驗(yàn)證下:

      第一個(gè)程序創(chuàng)建互斥量并等待用戶輸入后就觸發(fā)互斥量。第二個(gè)程序先打開(kāi)互斥量,成功后就等待并根據(jù)等待結(jié)果作相應(yīng)的輸出。詳見(jiàn)代碼:

      第一個(gè)程序:

      1. #include <stdio.h>  
      2. #include <conio.h>  
      3. #include <windows.h>  
      4. const char MUTEX_NAME[] = "Mutex_MoreWindows";  
      5. int main()  
      6. {  
      7.     HANDLE hMutex = CreateMutex(NULL, TRUE, MUTEX_NAME); //創(chuàng)建互斥量  
      8.     printf("互斥量已經(jīng)創(chuàng)建,現(xiàn)在按任意鍵觸發(fā)互斥量\n");  
      9.     getch();  
      10.     //exit(0);  
      11.     ReleaseMutex(hMutex);  
      12.     printf("互斥量已經(jīng)觸發(fā)\n");  
      13.     CloseHandle(hMutex);  
      14.     return 0;  
      15. }  

      第二個(gè)程序:

      1. #include <stdio.h>  
      2. #include <windows.h>  
      3. const char MUTEX_NAME[] = "Mutex_MoreWindows";  
      4. int main()  
      5. {  
      6.     HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, TRUE, MUTEX_NAME); //打開(kāi)互斥量  
      7.     if (hMutex == NULL)  
      8.     {  
      9.         printf("打開(kāi)互斥量失敗\n");  
      10.         return 0;  
      11.     }  
      12.     printf("等待中....\n");  
      13.     DWORD dwResult = WaitForSingleObject(hMutex, 20 * 1000); //等待互斥量被觸發(fā)  
      14.     switch (dwResult)  
      15.     {  
      16.     case WAIT_ABANDONED:  
      17.         printf("擁有互斥量的進(jìn)程意外終止\n");  
      18.         break;  
      19.   
      20.     case WAIT_OBJECT_0:  
      21.         printf("已經(jīng)收到信號(hào)\n");  
      22.         break;  
      23.   
      24.     case WAIT_TIMEOUT:  
      25.         printf("信號(hào)未在規(guī)定的時(shí)間內(nèi)送到\n");  
      26.         break;  
      27.     }  
      28.     CloseHandle(hMutex);  
      29.     return 0;  
      30. }  

      運(yùn)用這二個(gè)程序時(shí)要先啟動(dòng)程序一再啟動(dòng)程序二。下面展示部分輸出結(jié)果:

      結(jié)果一.二個(gè)進(jìn)程順利執(zhí)行完畢:

      結(jié)果二.將程序一中//exit(0);前面的注釋符號(hào)去掉,這樣程序一在觸發(fā)互斥量之前就會(huì)因?yàn)閳?zhí)行exit(0);語(yǔ)句而且退出,程序二會(huì)收到WAIT_ABANDONED消息并輸出“擁有互斥量的進(jìn)程意外終止”:

      有這個(gè)對(duì)“遺棄”問(wèn)題的處理,在多進(jìn)程中的線程同步也可以放心的使用互斥量。

       

      最后總結(jié)下互斥量Mutex

      1.互斥量是內(nèi)核對(duì)象,它與關(guān)鍵段都有“線程所有權(quán)”所以不能用于線程的同步。

      2.互斥量能夠用于多個(gè)進(jìn)程之間線程互斥問(wèn)題,并且能完美的解決某進(jìn)程意外終止所造成的“遺棄”問(wèn)題。

       

      下一篇《秒殺多線程第八篇 經(jīng)典線程同步 信號(hào)量Semaphore》將介紹使用信號(hào)量Semaphore來(lái)解決這個(gè)經(jīng)典線程同步問(wèn)題。

       

       

      轉(zhuǎn)載請(qǐng)標(biāo)明出處,原文地址:http://blog.csdn.net/morewindows/article/details/7470936

      如果覺(jué)得本文對(duì)您有幫助,請(qǐng)點(diǎn)擊支持一下,您的支持是我寫作最大的動(dòng)力,謝謝。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多