电竞比分网-中国电竞赛事及体育赛事平台

分享

臨界區(qū)實(shí)現(xiàn)線程同步互斥

 3dC 2014-02-13

除了臨界區(qū)對(duì)象進(jìn)能夠被用于一個(gè)進(jìn)程內(nèi)的線程使用外,臨界區(qū)對(duì)象同于其他互斥體對(duì)象一樣,也可以提供同步機(jī)制.事件,互斥體和信號(hào)量對(duì)象也能夠被用于單個(gè)進(jìn)程實(shí)現(xiàn)資源互斥訪問,與此相比,為了實(shí)現(xiàn)同步互斥訪問共享資源,臨界區(qū)對(duì)象提供一種更加輕巧,快速和有效的機(jī)制.象互斥體對(duì)象一樣,臨界區(qū)對(duì)象也可以被一個(gè)使用它來阻止同步訪問共享資源的線程所用于.例如:一個(gè)進(jìn)程隨時(shí)可以使用一個(gè)臨界區(qū)對(duì)象來阻止其他線程修改一個(gè)局?jǐn)?shù)據(jù)結(jié)構(gòu).
進(jìn)程負(fù)責(zé)為一個(gè)臨界區(qū)分配內(nèi)存.典型地,就是宣布一個(gè)CRITICAL_SECTION類型的變量.線程在使用它之前,臨界區(qū)對(duì)象必須使用InitializeCriticalSection函數(shù)進(jìn)行初始化.線程使用EnterCriticalSection或TryEnterCriticalSection函數(shù)獲取臨界區(qū)所有權(quán),并通過LeaveCriticalSection函數(shù)釋放臨界區(qū)所用權(quán).如果當(dāng)前臨界區(qū)對(duì)象被其他線程所擁有,EnterCriticalSection將無限等待為了臨界區(qū)所有權(quán).相比之下,一個(gè)互斥體對(duì)象為了互斥,等待函數(shù)會(huì)有一個(gè)指定的時(shí)間段.TryEnterCriticalSection函數(shù)無阻塞正在調(diào)用的線程而進(jìn)入臨界區(qū).
一旦線程擁有臨界區(qū),它必須額外的調(diào)用EnterCriticalSection或無阻塞他的執(zhí)行的TryEnterCriticalSection函數(shù).這樣以來,當(dāng)?shù)却粋€(gè)已存在的臨界區(qū)的擁有權(quán)時(shí),就不會(huì)出現(xiàn)死鎖自己.每當(dāng)它進(jìn)入臨界區(qū)時(shí),就必須調(diào)用LeaveCriticalSection來釋放對(duì)臨界區(qū)的擁有權(quán).
當(dāng)臨界區(qū)被初始化之后,進(jìn)程內(nèi)的任一個(gè)線程都可以調(diào)用DeleteCriticalSection函數(shù)來釋放被分配了的系統(tǒng)資源.DeleteCriticalSection函數(shù)被調(diào)用之后,這個(gè)臨界區(qū)對(duì)象就不能夠再被擁有為了同步機(jī)制了.
一旦一個(gè)臨界區(qū)對(duì)象被特有化之后,通過調(diào)用EnterCriticalSection函數(shù)而關(guān)聯(lián)度其它的線程將等待為了它的擁有權(quán).沒有等到擁有權(quán)的線程釋

放去繼續(xù)運(yùn)行.
SECTICAL_SECTION結(jié)構(gòu):
typedef struct _RTL_CRITICAL_SECTION {
    PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
    //
    //  The following three fields control entering and exiting the critical
    //  section for the resource
    //
    LONG LockCount;
    LONG RecursionCount;
    HANDLE OwningThread;        // from the thread's ClientId->UniqueThread
    HANDLE LockSemaphore;
    ULONG_PTR SpinCount;        // force size on 64-bit systems when packed
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;
typedef RTL_CRITICAL_SECTION CRITICAL_SECTION;
typedef PRTL_CRITICAL_SECTION PCRITICAL_SECTION;
typedef PRTL_CRITICAL_SECTION LPCRITICAL_SECTION;

操作臨界區(qū)的相關(guān)函數(shù)
(1)  InitializeCriticalSection
   初始化一個(gè)臨界區(qū)對(duì)象,而臨界區(qū)對(duì)象(數(shù)據(jù)成員)由系統(tǒng)自動(dòng)維護(hù).
   VOID InitializeCriticalSection(
       LPCRITICAL_SECTION lpCriticalSection //pointer to critical section object
   ); 
(2) DeleteCriticalSection 
    釋放一個(gè)沒有被占有的臨界區(qū)對(duì)象的所有資源.
    VOID DeleteCriticalSection(
        LPCRITICAL_SECTION lpCriticalSection //pointer to critical section object     
    );
(3)  EnterCriticalSection
   用來等待臨界區(qū)對(duì)象的所有權(quán),當(dāng)調(diào)用線程賦予所有權(quán),本函數(shù)返回,如果沒能等待到,那么導(dǎo)致線程暫停.
    VOID EnterCriticalSection(
       LPCRITICAL_SECTION lpCriticalSection //pointer to critical section object
    );
(4)  LeaveCriticalSection
   釋放指定臨界區(qū)對(duì)象所有權(quán)
   void LeaveCriticalSection(
       LPCRITICAL_SECTION lpCriticalSection //pointer to critical section object
   ); 
例子:
CRITICAL_SECTION g_cs; //臨界區(qū)對(duì)象
void main()
{
   HANDLE thread1 = CreateThread(NULL, 0, Fun1Proc, NULL, 0, NULL);
   HANDLE thread2 = CreateThread(NULL, 0, Fun2Proc, NULL, 0, NULL);
   CloseHandle(thread1);
   CloseHandle(thread2);
   //初始化一個(gè)臨界區(qū)對(duì)象
   InitializeCriticalSection(&g_cs);
   Sleep(4000);
   //釋放一個(gè)沒有被占有的臨界區(qū)對(duì)象的所有資源 
   DeleteCriticalSection(&g_cs);

}

DWORD WINAPI Fun1Proc(LPVOID lpParam)
{
   while(TRUE)
   {
       EnterCriticalSection(&g_cs);
       if (ticket>0)
       {
          cout<<"thread1 sells: "<<ticket--<<endl;
          Sleep(1);
       }
       else
          break;
       LeaveCriticalSection(&g_cs);
   }
   return 0;
}

DWORD WINAPI Fun1Proc(LPVOID lpParam)
{
   while(TRUE)
   {
       EnterCriticalSection(&g_cs);
       if (ticket>0)
       {
          cout<<"thread2 sells: "<<ticket--<<endl;
          Sleep(1);
       }
       else
          break;
       LeaveCriticalSection(&g_cs);
   }
   return 0;
}

//以下是我自己編寫實(shí)現(xiàn)臨界區(qū)的類:
//頭文件 CriticalSection.h
#pragma once
class CCriticalSection
{
private:
       CRITICAL_SECTION m_CS;
public:
       CCriticalSection()
       {
           ::InitializeCriticalSection(&m_CS);
       }
       ~CCriticalSection()
       {
           ::DeleteCriticalSection(&m_CS);
       }
       operator LPCRITICAL_SECTION()
       {
           return &m_CS;
       }
       void Lock()
       {
           ::EnterCriticalSection(&m_CS);
       }
       void UnLock()
       {
           ::LeaveCriticalSection(&m_CS);
       }
}; 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(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)論公約

    類似文章 更多