• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            大龍的博客

            常用鏈接

            統(tǒng)計(jì)

            最新評(píng)論

            信號(hào)量?jī)?nèi)核對(duì)象

            信號(hào)量(Semaphore)內(nèi)核對(duì)象對(duì)線程的同步方式與前面幾種方法不同,它允許多個(gè)線程在同一時(shí)刻訪問(wèn)同一資源,但是需要限制在同一時(shí)刻訪問(wèn)此資源的最大線程數(shù)目。在CreateSemaphore()創(chuàng)建信號(hào)量時(shí)即要同時(shí)指出允許的最大資源計(jì)數(shù)和當(dāng)前可資源計(jì)數(shù)。一般是將當(dāng)前可資源計(jì)數(shù)設(shè)置為最大資源計(jì)數(shù),每增加一個(gè)線程對(duì)共享資源的訪問(wèn),當(dāng)前可資源計(jì)數(shù)就會(huì)減1,只要當(dāng)前可資源計(jì)數(shù)是大于0的,就可以發(fā)出信號(hào)量信號(hào)。但是當(dāng)前可計(jì)數(shù)減小到0時(shí)則說(shuō)明當(dāng)前占資源的線程數(shù)已經(jīng)達(dá)到了所允許的最大數(shù)目,不能在允許其他線程的進(jìn)入,此時(shí)的信號(hào)量信號(hào)將無(wú)法發(fā)出。線程在處理完共享資源后,應(yīng)在離開(kāi)的同時(shí)通過(guò)ReleaseSemaphore()函數(shù)將當(dāng)前可資源計(jì)數(shù)加1。在任何時(shí)候當(dāng)前可資源計(jì)數(shù)決不可能大于最大資源計(jì)數(shù)。


            圖3 使信號(hào)量對(duì)象控制資源

              下面結(jié)合圖例3來(lái)演示信號(hào)量對(duì)象對(duì)資源的控制。在圖3中,以箭頭和白色箭頭表示共享資源所允許的最大資源計(jì)數(shù)和當(dāng)前可資源計(jì)數(shù)。初始如圖(a)所示,最大資源計(jì)數(shù)和當(dāng)前可資源計(jì)數(shù)均為4,此后每增加一個(gè)對(duì)資源進(jìn)行訪問(wèn)的線程(黑色箭頭表示)當(dāng)前資源計(jì)數(shù)就會(huì)相應(yīng)減1,圖(b)即表示的在3個(gè)線程對(duì)共享資源進(jìn)行訪問(wèn)時(shí)的狀態(tài)。當(dāng)進(jìn)入線程數(shù)達(dá)到4個(gè)時(shí),將如圖(c)所示,此時(shí)已達(dá)到最大資源計(jì)數(shù),而當(dāng)前可資源計(jì)數(shù)也已減到0,其他線程無(wú)法對(duì)共享資源進(jìn)行訪問(wèn)。在當(dāng)前占有資源的線程處理完畢而退出后,將會(huì)釋放出空間,圖(d)已有兩個(gè)線程退出對(duì)資源的占有,當(dāng)前可計(jì)數(shù)為2,可以再允許2個(gè)線程進(jìn)入到對(duì)資源的處理。可以看出,信號(hào)量是通過(guò)計(jì)數(shù)來(lái)對(duì)線程訪問(wèn)資源進(jìn)行控制的,而實(shí)際上信號(hào)量確實(shí)也被稱(chēng)作Dijkstra計(jì)數(shù)器。

              使信號(hào)量?jī)?nèi)核對(duì)象進(jìn)行線程同步主要會(huì)CreateSemaphore()、OpenSemaphore()、ReleaseSemaphore()、WaitForSingleObject()和WaitForMultipleObjects()等函數(shù)。其中,CreateSemaphore()來(lái)創(chuàng)建一個(gè)信號(hào)量?jī)?nèi)核對(duì)象,其函數(shù)原型為:

            HANDLE CreateSemaphore(
             LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // 安全屬性指針
             LONG lInitialCount, // 初始計(jì)數(shù)
             LONG lMaximumCount, // 最大計(jì)數(shù)
             LPCTSTR lpName // 對(duì)象名指針
            );

              參數(shù)lMaximumCount是一個(gè)有符號(hào)32位值,定義了允許的最大資源計(jì)數(shù),最大取值不能超過(guò)4294967295。lpName參數(shù)可以為創(chuàng)建的信號(hào)量定義一個(gè)名字,由于其創(chuàng)建的是一個(gè)內(nèi)核對(duì)象,因此在其他進(jìn)程中可以通過(guò)該名字而得到此信號(hào)量。OpenSemaphore()函數(shù)即可來(lái)根據(jù)信號(hào)量名打開(kāi)在其他進(jìn)程中創(chuàng)建的信號(hào)量,函數(shù)原型如下:

            HANDLE OpenSemaphore(
             DWORD dwDesiredAccess, // 訪問(wèn)標(biāo)志
             BOOL bInheritHandle, // 繼承標(biāo)志
             LPCTSTR lpName // 信號(hào)量名
            );

              在線程離開(kāi)對(duì)共享資源的處理時(shí),必須通過(guò)ReleaseSemaphore()來(lái)增加當(dāng)前可資源計(jì)數(shù)。否則將會(huì)出現(xiàn)當(dāng)前正在處理共享資源的實(shí)際線程數(shù)并沒(méi)有達(dá)到要限制的數(shù)值,而其他線程卻因?yàn)楫?dāng)前可資源計(jì)數(shù)為0而仍無(wú)法進(jìn)入的情況。ReleaseSemaphore()的函數(shù)原型為:

            BOOL ReleaseSemaphore(
             HANDLE hSemaphore, // 信號(hào)量句柄
             LONG lReleaseCount, // 計(jì)數(shù)遞增數(shù)量
             LPLONG lpPreviousCount // 先前計(jì)數(shù)
            );

              該函數(shù)將lReleaseCount中的值添加給信號(hào)量的當(dāng)前資源計(jì)數(shù),一般將lReleaseCount設(shè)置為1,如果需要也可以設(shè)置其他的值。WaitForSingleObject()和WaitForMultipleObjects()主要在試圖進(jìn)入共享資源的線程函數(shù)入口處,主要來(lái)判斷信號(hào)量的當(dāng)前可資源計(jì)數(shù)是否允許本線程的進(jìn)入。只有在當(dāng)前可資源計(jì)數(shù)值大于0時(shí),被監(jiān)視的信號(hào)量?jī)?nèi)核對(duì)象才會(huì)得到通知。

              信號(hào)量的使特點(diǎn)使其更適于對(duì)Socket(套接字)程序中線程的同步。例如,網(wǎng)絡(luò)上的HTTP服務(wù)器要對(duì)同一時(shí)間內(nèi)訪問(wèn)同一頁(yè)面的戶數(shù)加以限制,這時(shí)可以為沒(méi)一個(gè)戶對(duì)服務(wù)器的頁(yè)面請(qǐng)求設(shè)置一個(gè)線程,而頁(yè)面則是待保護(hù)的共享資源,通過(guò)使信號(hào)量對(duì)線程的同步作可以確保在任一時(shí)刻無(wú)論有多少戶對(duì)某一頁(yè)面進(jìn)行訪問(wèn),只有不大于設(shè)定的最大戶數(shù)目的線程能夠進(jìn)行訪問(wèn),而其他的訪問(wèn)企圖則被掛起,只有在有戶退出對(duì)此頁(yè)面的訪問(wèn)后才有可能進(jìn)入。下面給出的示例代碼即展示了類(lèi)似的處理過(guò)程:

            // 信號(hào)量對(duì)象句柄
            HANDLE hSemaphore;
            UINT ThreadProc15(LPVOID pParam)
            {
             // 試圖進(jìn)入信號(hào)量關(guān)口
             WaitForSingleObject(hSemaphore, INFINITE);
             // 線程任務(wù)處理
             AfxMessageBox("線程一正在執(zhí)行!");
             // 釋放信號(hào)量計(jì)數(shù)
             ReleaseSemaphore(hSemaphore, 1, NULL);
             return 0;
            }
            UINT ThreadProc16(LPVOID pParam)
            {
             // 試圖進(jìn)入信號(hào)量關(guān)口
             WaitForSingleObject(hSemaphore, INFINITE);
             // 線程任務(wù)處理
             AfxMessageBox("線程二正在執(zhí)行!");
             // 釋放信號(hào)量計(jì)數(shù)
             ReleaseSemaphore(hSemaphore, 1, NULL);
             return 0;
            }
            UINT ThreadProc17(LPVOID pParam)
            {
             // 試圖進(jìn)入信號(hào)量關(guān)口
             WaitForSingleObject(hSemaphore, INFINITE);
             // 線程任務(wù)處理
             AfxMessageBox("線程三正在執(zhí)行!");
             // 釋放信號(hào)量計(jì)數(shù)
             ReleaseSemaphore(hSemaphore, 1, NULL);
             return 0;
            }
            ……
            void CSample08View::OnSemaphore()
            {
             // 創(chuàng)建信號(hào)量對(duì)象
             hSemaphore = CreateSemaphore(NULL, 2, 2, NULL);
             // 開(kāi)啟線程
             AfxBeginThread(ThreadProc15, NULL);
             AfxBeginThread(ThreadProc16, NULL);
             AfxBeginThread(ThreadProc17, NULL);
            }


            圖4 開(kāi)始進(jìn)入的兩個(gè)線程


            圖5 線程二退出后線程三才得以進(jìn)入

              上述代碼在開(kāi)啟線程前首先創(chuàng)建了一個(gè)初始計(jì)數(shù)和最大資源計(jì)數(shù)均為2的信號(hào)量對(duì)象hSemaphore。即在同一時(shí)刻只允許2個(gè)線程進(jìn)入由hSemaphore保護(hù)的共享資源。隨后開(kāi)啟的三個(gè)線程均試圖訪問(wèn)此共享資源,在前兩個(gè)線程試圖訪問(wèn)共享資源時(shí),由于hSemaphore的當(dāng)前可資源計(jì)數(shù)分別為2和1,此時(shí)的hSemaphore是可以得到通知的,也就是說(shuō)位于線程入口處的WaitForSingleObject()將立即返回,而在前兩個(gè)線程進(jìn)入到保護(hù)區(qū)域后,hSemaphore的當(dāng)前資源計(jì)數(shù)減少到0,hSemaphore將不再得到通知,WaitForSingleObject()將線程掛起。直到此前進(jìn)入到保護(hù)區(qū)的線程退出后才能得以進(jìn)入。圖4和圖5為上述代脈的運(yùn)行結(jié)果。從實(shí)驗(yàn)結(jié)果可以看出,信號(hào)量始終保持了同一時(shí)刻不超過(guò)2個(gè)線程的進(jìn)入。

              在MFC中,通過(guò)CSemaphore類(lèi)對(duì)信號(hào)量作了表述。該類(lèi)只具有一個(gè)構(gòu)造函數(shù),可以構(gòu)造一個(gè)信號(hào)量對(duì)象,并對(duì)初始資源計(jì)數(shù)、最大資源計(jì)數(shù)、對(duì)象名和安全屬性等進(jìn)行初始化,其原型如下:

            CSemaphore( LONG lInitialCount = 1, LONG lMaxCount = 1, LPCTSTR pstrName = NULL, LPSECURITY_ATTRIBUTES lpsaAttributes = NULL );

              在構(gòu)造了CSemaphore類(lèi)對(duì)象后,任何一個(gè)訪問(wèn)受保護(hù)共享資源的線程都必須通過(guò)CSemaphore從父類(lèi)CSyncObject類(lèi)繼承得到的Lock()和UnLock()成員函數(shù)來(lái)訪問(wèn)或釋放CSemaphore對(duì)象。與前面介紹的幾種通過(guò)MFC類(lèi)保持線程同步的方法類(lèi)似,通過(guò)CSemaphore類(lèi)也可以將前面的線程同步代碼進(jìn)行改寫(xiě),這兩種使信號(hào)量的線程同步方法無(wú)論是在實(shí)現(xiàn)原理上還是從實(shí)現(xiàn)結(jié)果上都是完全一致的。下面給出經(jīng)MFC改寫(xiě)后的信號(hào)量線程同步代碼:

            // MFC信號(hào)量類(lèi)對(duì)象
            CSemaphore g_clsSemaphore(2, 2);
            UINT ThreadProc24(LPVOID pParam)
            {
             // 試圖進(jìn)入信號(hào)量關(guān)口
             g_clsSemaphore.Lock();
             // 線程任務(wù)處理
             AfxMessageBox("線程一正在執(zhí)行!");
             // 釋放信號(hào)量計(jì)數(shù)
             g_clsSemaphore.Unlock();
             return 0;
            }
            UINT ThreadProc25(LPVOID pParam)
            {
             // 試圖進(jìn)入信號(hào)量關(guān)口
             g_clsSemaphore.Lock();
             // 線程任務(wù)處理
             AfxMessageBox("線程二正在執(zhí)行!");
             // 釋放信號(hào)量計(jì)數(shù)
             g_clsSemaphore.Unlock();
             return 0;
            }
            UINT ThreadProc26(LPVOID pParam)
            {
             // 試圖進(jìn)入信號(hào)量關(guān)口
             g_clsSemaphore.Lock();
             // 線程任務(wù)處理
             AfxMessageBox("線程三正在執(zhí)行!");
             // 釋放信號(hào)量計(jì)數(shù)
             g_clsSemaphore.Unlock();
             return 0;
            }
            ……
            void CSample08View::OnSemaphoreMfc()
            {
             // 開(kāi)啟線程
             AfxBeginThread(ThreadProc24, NULL);
             AfxBeginThread(ThreadProc25, NULL);
             AfxBeginThread(ThreadProc26, NULL);
            }

            posted on 2008-07-30 17:44 大龍 閱讀(770) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            久久久久亚洲AV片无码下载蜜桃 | 久久精品国产久精国产果冻传媒| 久久香蕉超碰97国产精品| 久久亚洲视频| 久久夜色精品国产www| 久久99久久无码毛片一区二区 | 亚洲愉拍99热成人精品热久久| 久久精品国产福利国产琪琪| 久久93精品国产91久久综合| 久久精品中文字幕有码| 久久人人爽人爽人人爽av| 久久无码人妻精品一区二区三区 | 久久无码国产| 久久福利资源国产精品999| 久久精品亚洲AV久久久无码| 国产激情久久久久久熟女老人| 亚洲中文字幕无码一久久区| 三上悠亚久久精品| 亚洲国产精品久久66| 久久久久无码中| 久久亚洲精品成人av无码网站| 国产亚洲欧美精品久久久| 观看 国产综合久久久久鬼色 欧美 亚洲 一区二区 | 99久久777色| 亚洲国产成人精品女人久久久| 亚洲精品蜜桃久久久久久| 久久婷婷久久一区二区三区| 久久嫩草影院免费看夜色| 久久久久亚洲AV无码永不| 精品久久久久久99人妻| 亚洲中文字幕无码久久2017| 精品久久久无码中文字幕| 亚洲熟妇无码另类久久久| 天天久久狠狠色综合| 久久99精品国产麻豆宅宅| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 狠狠精品久久久无码中文字幕 | 亚洲&#228;v永久无码精品天堂久久| 99久久精品国产一区二区 | 久久e热在这里只有国产中文精品99| 国产香蕉久久精品综合网|