資源描述:
《Windows核心編程之線程同步》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在工程資料-天天文庫(kù)。
1、《WINDOWS核心編程》之五--線程的同步用戶方式中線程的同步?1.線程間的互鎖有時(shí)線程的某些步驟需要以原子的方式來(lái)進(jìn)行操作,尤其涉及到線程對(duì)內(nèi)存,資源的訪問的時(shí)候。Windows中,解決這個(gè)問題的辦法之一就是對(duì)線程中某些操作進(jìn)行互鎖。那么這些操作就會(huì)不被中斷而進(jìn)行。比如,使線程互鎖以對(duì)某個(gè)變量值進(jìn)行遞增操作的函數(shù):LONGInterlockedExchangeAdd(PLONGplAddend,LONGIncrement);舉一例:longg_x=0;DWORDWINAPIThreadFun1(PVOIDpvParam){InterlockedExchangeA
2、dd(&g_x,1);}DWORDWINAPIThreadFun2(PVOIDpvParam){InterlockedExchangeAdd(&g_x,2);}?通過這個(gè)小小的修改,g_x就可以以原子的方式來(lái)進(jìn)行遞增。不必清楚地了解互鎖函數(shù)是如何工作的。重要的是要知道,無(wú)論編譯器怎樣生成代碼,無(wú)論計(jì)算機(jī)中安裝了多少個(gè)CPU,它們都能保證以原子操作方式來(lái)修改一個(gè)值。還必須保證傳遞給這些函數(shù)的變量地址正確地對(duì)齊,否則這些函數(shù)就會(huì)運(yùn)行失敗?還有幾個(gè)修改變量的互鎖函數(shù)如下所示://改變某個(gè)變量值LONGInterlockedExchange(PLONGplTarget,LO
3、NGlValue);//改變指針的值PVOIDInterlockedExchangePointer(PVOID*ppvTarget,PVOIDpvValue);??實(shí)現(xiàn)循環(huán)鎖:可以用InterlockedExChange來(lái)實(shí)現(xiàn)循環(huán)鎖的功能,所謂循環(huán)鎖,就是在線程1中如果要對(duì)變量進(jìn)行操作,要先查看這個(gè)變量(或資源)有沒有被其它線程用到,如果是,則一直循環(huán),則到其它線程放棄對(duì)該變量(或資源)的控制。如果否,直接可以對(duì)該變量(或資源)進(jìn)行操作。如:?BOOLg_fResourceInUse=FALSE;voidFunc1(){//Waittoaccesstheresour
4、ce.等待資源while(InterlockedExchange(&g_fResourceInUse,TRUE)==TRUE)Sleep(0);//Accesstheresource.//獲取資源...////Wenolongerneedtoaccesstheresource.InterlockedExchange(&g_fResourceInUse,FALSE);//釋放資源}?其它線程如要使用資源也如上代碼所示。?OK,while循環(huán)是循環(huán)運(yùn)行的(假使本線程是ThreadA),它將g_fResourceInUse中的值改為TRUE,并查看它的前一個(gè)值,以了解它是
5、否是TRUE。如果是,則表示已經(jīng)有線程(假使為ThreadB)使用了,它就要等待,直到ThreadB線程執(zhí)行InterLockedExchange(&g_fResourceInUse,FALSE);操作,則ThreadA它就可以退出while循環(huán),然后獲取資源,并且,它對(duì)g_fResourceInUse設(shè)置為TURE,其它線程(假使ThreadC)如要使用,則將如剛才ThreadA般等待。直到ThreadA的InterlockedExchange(&g_fResourceInUse,FALSE);執(zhí)行完為止。?????2.關(guān)鍵代碼段?關(guān)鍵代碼段是指這樣一段代碼,它可
6、以在代碼執(zhí)行前,獨(dú)占對(duì)某資源的訪問權(quán)。這是能讓若干代碼能夠“以原子方式”來(lái)使用資源的另一種方法。注意,關(guān)鍵代碼段運(yùn)行中仍是可以被系統(tǒng)撤銷它的時(shí)間片,再調(diào)度給別的線程。但是,可調(diào)度線程有了變化,訪問該線程需要使用的資源的其它任何線程將得不到調(diào)度。關(guān)鍵代碼段的使用:constintMAX_TIMES=1000;intg_nIndex=0;DWORDg_dwTimes[MAX_TIMES];CRITICAL_SECTIONg_cs;?DWORDWINAPIFirstThread(PVOIDpvParam){while(g_nIndex7、iticalSection(&g_cs);g_dwTimes[g_nIndex]=GetTickCount();g_nIndex++;LeaveCriticalSection(&g_cs);}return(0);}DWORDWINAPISecondThread(PVOIDpvParam){while(g_nIndex