青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

asm, c, c++ are my all
-- Core In Computer
posts - 139,  comments - 123,  trackbacks - 0
windows核心編程--線程的同步

線程的同步

由于同一進(jìn)程的所有線程共享進(jìn)程的虛擬地址空間,并且線程的中斷是匯編語(yǔ)言級(jí)的,所以可能會(huì)發(fā)生兩個(gè)線程同時(shí)訪問(wèn)同一個(gè)對(duì)象(包括全局變量、共享資源、API函數(shù)和MFC對(duì)象等)的情況,這有可能導(dǎo)致程序錯(cuò)誤。屬于不同進(jìn)程的線程在同時(shí)訪問(wèn)同一內(nèi)存區(qū)域或共享資源時(shí),也會(huì)存在同樣的問(wèn)題。因此,在多線程應(yīng)用程序中,常常需要采取一些措施來(lái)同步線程的執(zhí)行。
需要同步的情況包括以下幾種:

在多個(gè)線程同時(shí)訪問(wèn)同一對(duì)象時(shí),可能產(chǎn)生錯(cuò)誤。例如,如果當(dāng)一個(gè)線程正在讀取一個(gè)至關(guān)重要的共享緩沖區(qū)時(shí),另一個(gè)線程向該緩沖區(qū)寫(xiě)入數(shù)據(jù),那么程序的運(yùn)行結(jié)果就可能出錯(cuò)。程序應(yīng)該盡量避免多個(gè)線程同時(shí)訪問(wèn)同一個(gè)緩沖區(qū)或系統(tǒng)資源。

Windows 95環(huán)境下編寫(xiě)多線程應(yīng)用程序還需要考慮重入問(wèn)題。Windows NT是真正的32位操作系統(tǒng),它解決了系統(tǒng)重入問(wèn)題。而Windows 95由于繼承了Windows 3.x的部分16位代碼,沒(méi)能夠解決重入問(wèn)題。這意味著在Windows 95中兩個(gè)線程不能同時(shí)執(zhí)行某個(gè)系統(tǒng)功能,否則有可能造成程序錯(cuò)誤,甚至?xí)斐上到y(tǒng)崩潰。應(yīng)用程序應(yīng)該盡量避免發(fā)生兩個(gè)以上的線程同時(shí)調(diào)用同一個(gè)Windows API函數(shù)的情況。

由于大小和性能方面的原因,

MFC對(duì)象在對(duì)象級(jí)不是線程安全的,只有在類級(jí)才是。也就是說(shuō),兩個(gè)線程可以安全地使用兩個(gè)不同的CString對(duì)象,但同時(shí)使用同一個(gè)CString對(duì)象就可能產(chǎn)生問(wèn)題。如果必須使用同一個(gè)對(duì)象,那么應(yīng)該采取適當(dāng)?shù)耐酱胧?

多個(gè)線程之間需要協(xié)調(diào)運(yùn)行。例如,如果第二個(gè)線程需要等待第一個(gè)線程完成到某一步時(shí)才能運(yùn)行,那么該線程應(yīng)該暫時(shí)掛起以減少對(duì)

CPU的占用時(shí)間,提高程序的執(zhí)行效率。當(dāng)?shù)谝粋€(gè)線程完成了相應(yīng)的步驟后,應(yīng)該發(fā)出某種信號(hào)來(lái)激活第二個(gè)線程。

關(guān)鍵節(jié)和互鎖變量訪問(wèn)

關(guān)鍵節(jié) (Critical Seciton)mutex 的功能類似,但它只能由同一進(jìn)程中的線程使用。關(guān)鍵節(jié)可以防止共享資源被同時(shí)訪問(wèn)。

進(jìn)程負(fù)責(zé)為關(guān)鍵節(jié)分配內(nèi)存空間,關(guān)鍵節(jié)實(shí)際上是一個(gè)CRITICAL_SECTION型的變量,它一次只能被一個(gè)線程擁有。在線程使用關(guān)鍵節(jié)之前,必須調(diào)用InitializeCriticalSection函數(shù)將其初始化。如果線程中有一段關(guān)鍵的代碼不希望被別的線程中斷,那么可以調(diào)用EnterCriticalSection函數(shù)來(lái)申請(qǐng)關(guān)鍵節(jié)的所有權(quán),在運(yùn)行完關(guān)鍵代碼后再用LeaveCriticalSection函數(shù)來(lái)釋放所有權(quán)。如果在調(diào)用EnterCriticalSection時(shí)關(guān)鍵節(jié)對(duì)象已被另一個(gè)線程擁有,那么該函數(shù)將無(wú)限期等待所有權(quán)。

利用互鎖變量可以建立簡(jiǎn)單有效的同步機(jī)制。使用函數(shù)InterlockedIncrementInterlockedDecrement可以增加或減少多個(gè)線程共享的一個(gè)32位變量的值,并且可以檢查結(jié)果是否為0。線程不必?fù)?dān)心會(huì)被其它線程中斷而導(dǎo)致錯(cuò)誤。如果變量位于共享內(nèi)存中,那么不同進(jìn)程中的線程也可以使用這種機(jī)制。

原子訪問(wèn)


所謂原子訪問(wèn),是指線程在訪問(wèn)資源時(shí)能夠確保所有其他線程都不在同一時(shí)間內(nèi)訪問(wèn)相同的資源。互鎖的函數(shù)家族:

				
				
				
LONG?InterlockedExchangeAdd(
???PLONG?plAddend,
???LONG?Increment);

這是個(gè)最簡(jiǎn)單的函數(shù)了。只需調(diào)用這個(gè)函數(shù),傳遞一個(gè)長(zhǎng)變量地址,并指明將這個(gè)值遞增多少即可。但是這個(gè)函數(shù)能夠保證值的遞增以原子操作方式來(lái)完成。

						LONG InterlockedExchange(PLONG plTarget,
   LONG lValue);

PVOID InterlockedExchangePointer(PVOID* ppvTarget,
   PVOID pvValue);
				

I n t e r l o c k e d E x c h a n g e和I n t e r l o c k e d E x c h a n g e P o i n t e r能夠以原子操作方式用第二個(gè)參數(shù)中傳遞的值來(lái)取代第一個(gè)參數(shù)中傳遞的當(dāng)前值。
------------------------------以上為用戶方式同步,以下為內(nèi)核方式同步---------------------------------

等待函數(shù)

等待函數(shù)可使線程自愿進(jìn)入等待狀態(tài),直到一個(gè)特定的內(nèi)核對(duì)象變?yōu)橐淹ㄖ獱顟B(tài)為止。 ???


DWORD?WaitForSingleObject(HANDLE?hObject,
???DWORD?dwMilliseconds);


函數(shù)Wa i t F o r M u l t i p l e O b j e c t s與Wa i t F o r S i n g l e O b j e c t函數(shù)很相似,區(qū)別在于它允許調(diào)用線程同時(shí)查看若干個(gè)內(nèi)核對(duì)象的已通知狀態(tài):

						DWORD WaitForMultipleObjects(DWORD dwCount,
   CONST HANDLE* phObjects, 
   BOOL fWaitAll, 
   DWORD dwMilliseconds);
				

同步對(duì)象

同步對(duì)象用來(lái)協(xié)調(diào)多線程的執(zhí)行,它可以被多個(gè)線程共享。線程的等待函數(shù)用同步對(duì)象的句柄作為參數(shù),同步對(duì)象應(yīng)該是所有要使用的線程都能訪問(wèn)到的。同步對(duì)象的狀態(tài)要么是有信號(hào)的,要么是無(wú)信號(hào)的。同步對(duì)象主要有三種:事件、 mutex 和信號(hào)燈。

事件對(duì)象 (Event) 是最簡(jiǎn)單的同步對(duì)象,它包括有信號(hào)和無(wú)信號(hào)兩種狀態(tài)。在線程訪問(wèn)某一資源之前,也許需要等待某一事件的發(fā)生,這時(shí)用事件對(duì)象最合適。例如,只有在通信端口緩沖區(qū)收到數(shù)據(jù)后,監(jiān)視線程才被激活。

事件對(duì)象是用 CreateEvent 函數(shù)建立的。該函數(shù)可以指定事件對(duì)象的種類和事件的初始狀態(tài)。如果是手工重置事件,那么它總是保持有信號(hào)狀態(tài),直到用 ResetEvent 函數(shù)重置成無(wú)信號(hào)的事件。如果是自動(dòng)重置事件,那么它的狀態(tài)在單個(gè)等待線程釋放后會(huì)自動(dòng)變?yōu)闊o(wú)信號(hào)的。用 SetEvent 可以把事件對(duì)象設(shè)置成有信號(hào)狀態(tài)。在建立事件時(shí),可以為對(duì)象起個(gè)名字,這樣其它進(jìn)程中的線程可以用 OpenEvent 函數(shù)打開(kāi)指定名字的事件對(duì)象句柄。

mutex對(duì)象的狀態(tài)在它不被任何線程擁有時(shí)是有信號(hào)的,而當(dāng)它被擁有時(shí)則是無(wú)信號(hào)的。mutex對(duì)象很適合用來(lái)協(xié)調(diào)多個(gè)線程對(duì)共享資源的互斥訪問(wèn)(mutually exclusive)

線程用 CreateMutex 函數(shù)來(lái)建立 mutex 對(duì)象,在建立 mutex 時(shí),可以為對(duì)象起個(gè)名字,這樣其它進(jìn)程中的線程可以用 OpenMutex 函數(shù)打開(kāi)指定名字的 mutex 對(duì)象句柄。在完成對(duì)共享資源的訪問(wèn)后,線程可以調(diào)用 ReleaseMutex 來(lái)釋放 mutex ,以便讓別的線程能訪問(wèn)共享資源。如果線程終止而不釋放 mutex ,則認(rèn)為該 mutex 被廢棄。

信號(hào)燈對(duì)象維護(hù)一個(gè)從 0 開(kāi)始的計(jì)數(shù),在計(jì)數(shù)值大于 0 時(shí)對(duì)象是有信號(hào)的,而在計(jì)數(shù)值為 0 時(shí)則是無(wú)信號(hào)的。信號(hào)燈對(duì)象可用來(lái)限制對(duì)共享資源進(jìn)行訪問(wèn)的線程數(shù)量。線程用 CreateSemaphore 函數(shù)來(lái)建立信號(hào)燈對(duì)象,在調(diào)用該函數(shù)時(shí),可以指定對(duì)象的初始計(jì)數(shù)和最大計(jì)數(shù)。在建立信號(hào)燈時(shí)也可以為對(duì)象起個(gè)名字,別的進(jìn)程中的線程可以用 OpenSemaphore 函數(shù)打開(kāi)指定名字的信號(hào)燈句柄。

一般把信號(hào)燈的初始計(jì)數(shù)設(shè)置成最大值。每次當(dāng)信號(hào)燈有信號(hào)使等待函數(shù)返回時(shí),信號(hào)燈計(jì)數(shù)就會(huì)減 1 ,而調(diào)用 ReleaseSemaphore 可以增加信號(hào)燈的計(jì)數(shù)。計(jì)數(shù)值越小就表明訪問(wèn)共享資源的程序越多。

可用于同步的對(duì)象

對(duì)象

描述

變化通知

FindFirstChangeNotification 函數(shù)建立,當(dāng)在指定目錄中發(fā)生指定類型的變化時(shí)對(duì)象變成有信號(hào)的。

控制臺(tái)輸入

在控制臺(tái)建立是被創(chuàng)建。它是用

CONIN$ 調(diào)用 CreateFile 函數(shù)返回的句柄,或是 GetStdHandle 函數(shù)的返回句柄。如果控制臺(tái)輸入緩沖區(qū)中有數(shù)據(jù),那么對(duì)象是有信號(hào)的,如果緩沖區(qū)為空,則對(duì)象是無(wú)信號(hào)的。

進(jìn)程

當(dāng)調(diào)用

CreateProcess 建立進(jìn)程時(shí)被創(chuàng)建。進(jìn)程在運(yùn)行時(shí)對(duì)象是無(wú)信號(hào)的,當(dāng)進(jìn)程終止時(shí)對(duì)象是有信號(hào)的。

線程

當(dāng)調(diào)用

CreateprocessCreateThreadCreateRemoteThread 函數(shù)創(chuàng)建新線程時(shí)被創(chuàng)建。在線程運(yùn)行是對(duì)象是無(wú)信號(hào)的,在線程終止時(shí)則是有信號(hào)的。
另外,有時(shí)可以用文件或通信設(shè)備作為同步對(duì)象使用。

事件內(nèi)核對(duì)象

讓我們觀察一個(gè)簡(jiǎn)單的例子,以便說(shuō)明如何使用事件內(nèi)核對(duì)象對(duì)線程進(jìn)行同步。下面就是這個(gè)代碼:

										// Create a global handle to a manual-reset, nonsignaled event.
HANDLE g_hEvent;

int WINAPI WinMain(...) 
{
   //Create the manual-reset, nonsignaled event.
   g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

   //Spawn 3 new threads.
   HANDLE hThread[3];
   DWORD dwThreadID;
   hThread[0] = _beginthreadex(NULL, 0, WordCount, NULL, 0, &dwThreadID);
   hThread[1] = _beginthreadex(NULL, 0, SpellCheck, NULL, 0, &dwThreadID);
   hThread[2] = _beginthreadex(NULL, 0, GrammarCheck, NULL, 0, &dwThreadID);

   OpenFileAndReadContentsIntoMemory(...);

   //Allow all 3 threads to access the memory.
   SetEvent(g_hEvent);
   ...
}

DWORD WINAPI WordCount(PVOID pvParam)
{
   //Wait until the file's data is in memory.
   WaitForSingleObject(g_hEvent, INFINITE);

   //Access the memory block.
   ...
   return(0);
}

DWORD WINAPI SpellCheck(PVOID pvParam)
{
   //Wait until the file's data is in memory.
   WaitForSingleObject(g_hEvent, INFINITE);

   //Access the memory block.
   ...
   return(0);
}

DWORD WINAPI GrammarCheck(PVOID pvParam)
{
   //Wait until the file's data is in memory.
   WaitForSingleObject(g_hEvent, INFINITE);

   //Access the memory block.
   ...
   return(0);
}
								
當(dāng)這個(gè)進(jìn)程啟動(dòng)時(shí),它創(chuàng)建一個(gè)人工重置的未通知狀態(tài)的事件,并且將句柄保存在一個(gè)全局變量中。這使得該進(jìn)程中的其他線程能夠非常容易地訪問(wèn)同一個(gè)事件對(duì)象。現(xiàn)在3個(gè)線程已經(jīng)產(chǎn)生。這些線程要等待文件的內(nèi)容讀入內(nèi)存,然后每個(gè)線程都要訪問(wèn)它的數(shù)據(jù)。一個(gè)線程進(jìn)行單詞計(jì)數(shù),另一個(gè)線程運(yùn)行拼寫(xiě)檢查器,第三個(gè)線程運(yùn)行語(yǔ)法檢查器。這3個(gè)線程函數(shù)的代碼的開(kāi)始部分都相同,每個(gè)函數(shù)都調(diào)用Wa i t F o r S i n g l e O b j e c t,這將使線程暫停運(yùn)行,直到文件的內(nèi)容由主線程讀入內(nèi)存為止。

一旦主線程將數(shù)據(jù)準(zhǔn)備好,它就調(diào)用S e t E v e n t,給事件發(fā)出通知信號(hào)。這時(shí),系統(tǒng)就使所有這3個(gè)輔助線程進(jìn)入可調(diào)度狀態(tài),它們都獲得了C P U時(shí)間,并且可以訪問(wèn)內(nèi)存塊。注意,這3個(gè)線程都以只讀方式訪問(wèn)內(nèi)存。這就是所有3個(gè)線程能夠同時(shí)運(yùn)行的唯一原因。還要注意,如何計(jì)算機(jī)上配有多個(gè)C P U,那么所有3個(gè)線程都能夠真正地同時(shí)運(yùn)行,從而可以在很短的時(shí)間內(nèi)完成大量的操作。

如果你使用自動(dòng)重置的事件而不是人工重置的事件,那么應(yīng)用程序的行為特性就有很大的差別。當(dāng)主線程調(diào)用S e t E v e n t之后,系統(tǒng)只允許一個(gè)輔助線程變成可調(diào)度狀態(tài)。同樣,也無(wú)法保證系統(tǒng)將使哪個(gè)線程變?yōu)榭烧{(diào)度狀態(tài)。其余兩個(gè)輔助線程將繼續(xù)等待。

已經(jīng)變?yōu)榭烧{(diào)度狀態(tài)的線程擁有對(duì)內(nèi)存塊的獨(dú)占訪問(wèn)權(quán)。讓我們重新編寫(xiě)線程的函數(shù),使得每個(gè)函數(shù)在返回前調(diào)用S e t E v e n t函數(shù)(就像Wi n M a i n函數(shù)所做的那樣)。這些線程函數(shù)現(xiàn)在變成下面的形式:

										DWORD WINAPI WordCount(PVOID pvParam)
{
   //Wait until the file's data is in memory.
   WaitForSingleObject(g_hEvent, INFINITE);

   //Access the memory block.
   ...
   SetEvent(g_hEvent);
   return(0);
}

DWORD WINAPI SpellCheck(PVOID pvParam) 
{
   //Wait until the file's data is in memory.
   WaitForSingleObject(g_hEvent, INFINITE);

   //Access the memory block.
   ...
   SetEvent(g_hEvent);
   return(0);
}

DWORD WINAPI GrammarCheck(PVOID pvParam)
{
   //Wait until the file's data is in memory.
   WaitForSingleObject(g_hEvent, INFINITE);

   //Access the memory block.
   ...
   SetEvent(g_hEvent);
   return(0);
}
								
當(dāng)線程完成它對(duì)數(shù)據(jù)的專門(mén)傳遞時(shí),它就調(diào)用S e t E v e n t函數(shù),該函數(shù)允許系統(tǒng)使得兩個(gè)正在等待的線程中的一個(gè)成為可調(diào)度線程。同樣,我們不知道系統(tǒng)將選擇哪個(gè)線程作為可調(diào)度線程,但是該線程將進(jìn)行它自己的對(duì)內(nèi)存塊的專門(mén)傳遞。當(dāng)該線程完成操作時(shí),它也將調(diào)用S e t E v e n t函數(shù),使第三個(gè)即最后一個(gè)線程進(jìn)行它自己的對(duì)內(nèi)存塊的傳遞。注意,當(dāng)使用自動(dòng)重置事件時(shí),如果每個(gè)輔助線程均以讀/寫(xiě)方式訪問(wèn)內(nèi)存塊,那么就不會(huì)產(chǎn)生任何問(wèn)題,這些線程將不再被要求將數(shù)據(jù)視為只讀數(shù)據(jù)。


等待定時(shí)器內(nèi)核對(duì)象

等待定時(shí)器是在某個(gè)時(shí)間或按規(guī)定的間隔時(shí)間發(fā)出自己的信號(hào)通知的內(nèi)核對(duì)象。它們通常用來(lái)在某個(gè)時(shí)間執(zhí)行某個(gè)操作。

若要?jiǎng)?chuàng)建等待定時(shí)器,只需要調(diào)用C r e a t e Wa i t a b l e Ti m e r函數(shù):

						HANDLE CreateWaitableTimer(
   PSECURITY_ATTRIBUTES psa,
   BOOL fManualReset,
   PCTSTR pszName);
				
進(jìn)程可以獲得它自己的與進(jìn)程相關(guān)的現(xiàn)有等待定時(shí)器的句柄,方法是調(diào)用O p e n Wa i t a b l e Ti m e r函數(shù):

						HANDLE OpenWaitableTimer(
   DWORD dwDesiredAccess,
   BOOL bInheritHandle,
   PCTSTR pszName);
				
當(dāng)發(fā)出人工重置的定時(shí)器信號(hào)通知時(shí),等待該定時(shí)器的所有線程均變?yōu)榭烧{(diào)度線程。當(dāng)發(fā)出自動(dòng)重置的定時(shí)器信號(hào)通知時(shí),只有一個(gè)等待的線程變?yōu)榭烧{(diào)度線程。

等待定時(shí)器對(duì)象總是在未通知狀態(tài)中創(chuàng)建。必須調(diào)用S e t Wa i t a b l e Ti m e r函數(shù)來(lái)告訴定時(shí)器你想在何時(shí)讓它成為已通知狀態(tài):

						BOOL SetWaitableTimer(
   HANDLE hTimer,
   const LARGE_INTEGER *pDueTime,
   LONG lPeriod,
   PTIMERAPCROUTINE pfnCompletionRoutine,
   PVOID pvArgToCompletionRoutine,
   BOOL fResume);
				
定時(shí)器函數(shù)外,最后還有一個(gè)C a n c e l Wa i t a b l e Ti m e r函數(shù):

						BOOL CancelWaitableTimer(HANDLE hTimer);
				
這個(gè)簡(jiǎn)單的函數(shù)用于取出定時(shí)器的句柄并將它撤消,這樣,除非接著調(diào)用S e t Wa i t a b l e Ti m e r函數(shù)以便重新設(shè)置定時(shí)器,否則定時(shí)器決不會(huì)進(jìn)行報(bào)時(shí)。

信標(biāo)內(nèi)核對(duì)象

信標(biāo)內(nèi)核對(duì)象用于對(duì)資源進(jìn)行計(jì)數(shù)。它們與所有內(nèi)核對(duì)象一樣,包含一個(gè)使用數(shù)量,但是它們也包含另外兩個(gè)帶符號(hào)的3 2位值,一個(gè)是最大資源數(shù)量,一個(gè)是當(dāng)前資源數(shù)量。最大資源數(shù)量用于標(biāo)識(shí)信標(biāo)能夠控制的資源的最大數(shù)量,而當(dāng)前資源數(shù)量則用于標(biāo)識(shí)當(dāng)前可以使用的資源的數(shù)量。

信標(biāo)的使用規(guī)則如下:

? 如果當(dāng)前資源的數(shù)量大于0,則發(fā)出信標(biāo)信號(hào)。

? 如果當(dāng)前資源數(shù)量是0,則不發(fā)出信標(biāo)信號(hào)。

? 系統(tǒng)決不允許當(dāng)前資源的數(shù)量為負(fù)值。

? 當(dāng)前資源數(shù)量決不能大于最大資源數(shù)量。

下面的函數(shù)用于創(chuàng)建信標(biāo)內(nèi)核對(duì)象:

								HANDLE CreateSemaphore(
   PSECURITY_ATTRIBUTE psa,
   LONG lInitialCount,
   LONG lMaximumCount,
   PCTSTR pszName);
						
通過(guò)調(diào)用O p e n S e m a p h o r e函數(shù),另一個(gè)進(jìn)程可以獲得它自己的進(jìn)程與現(xiàn)有信標(biāo)相關(guān)的句柄:

						HANDLE OpenSemaphore(
   DWORD fdwAccess,
   BOOL bInheritHandle,
   PCTSTR pszName);
				

通過(guò)調(diào)用R e l e a s e S e m a p h o r e函數(shù),線程就能夠?qū)π艠?biāo)的當(dāng)前資源數(shù)量進(jìn)行遞增:

						BOOL ReleaseSemaphore(
   HANDLE hsem,
   LONG lReleaseCount,
   PLONG plPreviousCount);
				
互斥對(duì)象內(nèi)核對(duì)象

互斥對(duì)象(m u t e x)內(nèi)核對(duì)象能夠確保線程擁有對(duì)單個(gè)資源的互斥訪問(wèn)權(quán)。
互斥對(duì)象有許多用途,屬于最常用的內(nèi)核對(duì)象之一。通常來(lái)說(shuō),它們用于保護(hù)由多個(gè)線程訪問(wèn)的內(nèi)存塊。如果多個(gè)線程要同時(shí)訪問(wèn)內(nèi)存塊,內(nèi)存塊中的數(shù)據(jù)就可能遭到破壞。互斥對(duì)象能夠保證訪問(wèn)內(nèi)存塊的任何線程擁有對(duì)該內(nèi)存塊的獨(dú)占訪問(wèn)權(quán),這樣就能夠保證數(shù)據(jù)的完整性。

互斥對(duì)象的使用規(guī)則如下:

? 如果線程I D是0(這是個(gè)無(wú)效I D),互斥對(duì)象不被任何線程所擁有,并且發(fā)出該互斥對(duì)象的通知信號(hào)。

? 如果I D是個(gè)非0數(shù)字,那么一個(gè)線程就擁有互斥對(duì)象,并且不發(fā)出該互斥對(duì)象的通知信號(hào)。

? 與所有其他內(nèi)核對(duì)象不同, 互斥對(duì)象在操作系統(tǒng)中擁有特殊的代碼,允許它們違反正常的規(guī)則(后面將要介紹這個(gè)異常情況)。

若要使用互斥對(duì)象,必須有一個(gè)進(jìn)程首先調(diào)用C r e a t e M u t e x,以便創(chuàng)建互斥對(duì)象:

						HANDLE CreateMutex(
   PSECURITY_ATTRIBUTES psa,
   BOOL fInitialOwner,
   PCTSTR pszName);
				

通過(guò)調(diào)用O p e n M u t e x,另一個(gè)進(jìn)程可以獲得它自己進(jìn)程與現(xiàn)有互斥對(duì)象相關(guān)的句柄:

						HANDLE OpenMutex(
   DWORD fdwAccess,
   BOOL bInheritHandle,
   PCTSTR pszName);
				

一旦線程成功地等待到一個(gè)互斥對(duì)象,該線程就知道它已經(jīng)擁有對(duì)受保護(hù)資源的獨(dú)占訪問(wèn)權(quán)。試圖訪問(wèn)該資源的任何其他線程(通過(guò)等待相同的互斥對(duì)象)均被置于等待狀態(tài)中。當(dāng)目前擁有對(duì)資源的訪問(wèn)權(quán)的線程不再需要它的訪問(wèn)權(quán)時(shí),它必須調(diào)用R e l e a s e M u t e x函數(shù)來(lái)釋放該互斥對(duì)象:

						BOOL ReleaseMutex(HANDLE hMutex);
				

該函數(shù)將對(duì)象的遞歸計(jì)數(shù)器遞減1。

互斥對(duì)象與關(guān)鍵代碼段的比較

就等待線程的調(diào)度而言,互斥對(duì)象與關(guān)鍵代碼段之間有著相同的特性。但是它們?cè)谄渌麑傩苑矫鎱s各不相同。表9 - 1對(duì)它們進(jìn)行了各方面的比較。

表9-1 互斥對(duì)象與關(guān)鍵代碼段的比較

特性 互斥對(duì)象 關(guān)鍵代碼段
運(yùn)行速度
是否能夠跨進(jìn)程邊界來(lái)使用
聲明 HANDLE hmtx; CRITICAL_SECTION cs;
初始化 h m t x = C r e a t e M u t e x(N U L L,F(xiàn)A L S E,N U L L); I n i t i a l i z e C r i t i c a l S e c t i o n ( & e s );
清除 C l o s e H a n d l e(h m t x); D e l e t e C r i t i c a l S e c t i o n(& c s);
無(wú)限等待 Wa i t F o r S i n g l e O b j e c t(h m t x , I N F I N I T E); E n t e r C r i t i c a l S e c t i o n(& c s);
0等待 Wa i t F o r S i n g l e O b j e c t Tr y(h m t x , 0); E n t e r C r i t i c a l S e c t i o n(& c s);
任意等待 Wa i t F o r S i n g l e O b j e c t(h m t x , d w M i l l i s e c o n d s); 不能
釋放 R e l e a s e M u t e x(h m t x); L e a v e C r i t i c a l S e c t i o n(& c s);
是否能夠等待其他內(nèi)核對(duì)象 是(使用Wa i t F o r M u l t i p l e O b j e c t s或類似的函數(shù))

線程同步對(duì)象速查表

內(nèi)核對(duì)象與線程同步之間的相互關(guān)系
對(duì)象 何時(shí)處于未通知狀態(tài) 何時(shí)處于已通知狀態(tài) 成功等待的副作用
進(jìn)程 當(dāng)進(jìn)程仍然活動(dòng)時(shí) 當(dāng)進(jìn)程終止運(yùn)行時(shí)(E x i t P r o c e s s,Te r m i n a t e P r o c e s s) 無(wú)
線程 當(dāng)線程仍然活動(dòng)時(shí) 當(dāng)線程終止運(yùn)行時(shí)(E x i t T h r e a d,Te r m i n a t e T h r e a d) 無(wú)
作業(yè) 當(dāng)作業(yè)的時(shí)間尚未結(jié)束時(shí) 當(dāng)作業(yè)的時(shí)間已經(jīng)結(jié)束時(shí) 無(wú)
文件 當(dāng)I / O請(qǐng)求正在處理時(shí) 當(dāng)I / O請(qǐng)求處理完畢時(shí) 無(wú)
控制臺(tái)輸入 不存在任何輸入 當(dāng)存在輸入時(shí) 無(wú)
文件修改通知 沒(méi)有任何文件被修改 當(dāng)文件系統(tǒng)發(fā)現(xiàn)修改時(shí) 重置通知
自動(dòng)重置事件 R e s e t E v e n t , P u l s e - E v e n t或等待成功 當(dāng)調(diào)用S e t E v e n t / P u l s e E v e n t時(shí) 重置事件
人工重置事件 R e s e t E v e n t或P u l s e E v e n t 當(dāng)調(diào)用S e t E v e n t / P u l s e E v e n t時(shí) 無(wú)
自動(dòng)重置等待定時(shí)器 C a n c e l Wa i t a b l e Ti m e r或等待成功 當(dāng)時(shí)間到時(shí)(S e t Wa i t a b l e Ti m e r) 重置定時(shí)器
人工重置等待定時(shí)器 C a n c e l Wa i t a b l e Ti m e r 當(dāng)時(shí)間到時(shí)(S e t Wa i t a b l e Ti m e r) 無(wú)
信標(biāo) 等待成功 當(dāng)數(shù)量> 0時(shí)(R e l e a s e S e m a p h o r e) 數(shù)量遞減1
互斥對(duì)象 等待成功 當(dāng)未被線程擁有時(shí)(R e l e a s e互斥對(duì)象) 將所有權(quán)賦予線程
關(guān)鍵代碼段(用戶方式) 等待成功((Tr y)E n t e r C r i t i c a l S e c t i o n) 當(dāng)未被線程擁有時(shí)(L e a v e C r i t i c a l S e c t i o n) 將所有權(quán)賦予線程


其他的線程同步函數(shù)

1 異步設(shè)備I / O使得線程能夠啟動(dòng)一個(gè)讀操作或?qū)懖僮鳎遣槐氐却x操作或?qū)懖僮魍瓿伞@纾绻€程需要將一個(gè)大文件裝入內(nèi)存,那么該線程可以告訴系統(tǒng)將文件裝入內(nèi)存。然后,當(dāng)系統(tǒng)加載該文件時(shí),該線程可以忙于執(zhí)行其他任務(wù),如創(chuàng)建窗口、對(duì)內(nèi)部數(shù)據(jù)結(jié)構(gòu)進(jìn)行初始化等等。當(dāng)初始化操作完成時(shí),該線程可以終止自己的運(yùn)行,等待系統(tǒng)通知它文件已經(jīng)讀取。

2 線程也可以調(diào)用Wa i t F o r I n p u t I d l e來(lái)終止自己的運(yùn)行:

												DWORD WaitForInputIdle(
   HANDLE hProcess,
   DWORD dwMilliseconds);
										

該函數(shù)將一直處于等待狀態(tài),直到h P r o c e s s標(biāo)識(shí)的進(jìn)程在創(chuàng)建應(yīng)用程序的第一個(gè)窗口的線程中已經(jīng)沒(méi)有尚未處理的輸入為止。這個(gè)函數(shù)可以用于父進(jìn)程。父進(jìn)程產(chǎn)生子進(jìn)程,以便執(zhí)行某些操作。
3 線程可以調(diào)用M s g Wa i t F o r M u l t i p l e O b j e c t s或M s g Wa i t F o r M u l t i p l e O b j e c t s E x函數(shù),讓線程等待它自己的消息:

												DWORD MsgWaitForMultipleObjects(
   DWORD dwCount,
   PHANDLE phObjects,
   BOOL fWaitAll,
   DWORD dwMilliseconds,
   DWORD dwWakeMask);

DWORD MsgWaitForMultipleObjectsEx(
   DWORD dwCount,
   PHANDLE phObjects,
   DWORD dwMilliseconds,
   DWORD dwWakeMask,
   DWORD dwFlags);
										

這些函數(shù)與Wa i t F o r M u l t i p l e O b j e c t s函數(shù)十分相似。差別在于它們?cè)试S線程在內(nèi)核對(duì)象變成已通知狀態(tài)或窗口消息需要調(diào)度到調(diào)用線程創(chuàng)建的窗口中時(shí)被調(diào)度。

4 Wi n d o w s將非常出色的調(diào)試支持特性內(nèi)置于操作系統(tǒng)之中。當(dāng)調(diào)試程序啟動(dòng)運(yùn)行時(shí),它將自己附加給一個(gè)被調(diào)試程序。該調(diào)試程序只需閑置著,等待操作系統(tǒng)將與被調(diào)試程序相關(guān)的調(diào)試事件通知它。調(diào)試程序通過(guò)調(diào)用Wa i t F o r D e b u g E v e n t函數(shù)來(lái)等待這些事件的發(fā)生:

												BOOL WaitForDebugEvent(
   PDEBUG_EVENT pde,
   DWORD dwMilliseconds);
										

當(dāng)調(diào)試程序調(diào)用該函數(shù)時(shí),調(diào)試程序的線程終止運(yùn)行,系統(tǒng)將調(diào)試事件已經(jīng)發(fā)生的情況通知調(diào)試程序,方法是允許調(diào)用的Wa i t F o r D e b u g E v e n t函數(shù)返回。

5 S i n g l e O b j e c t A n d Wa i t函數(shù)用于在單個(gè)原子方式的操作中發(fā)出關(guān)于內(nèi)核對(duì)象的通知并等待另一個(gè)內(nèi)核對(duì)象:

												DWORD SingleObjectAndWait(
   HANDLE hObjectToSignal,
   HANDLE hObjectToWaitOn,
   DWORD  dwMilliseconds,
   BOOL   fAlertable);
										
posted on 2006-10-13 19:47 Jerry Cat 閱讀(551) 評(píng)論(0)  編輯 收藏 引用

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



<2025年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用鏈接

留言簿(7)

隨筆檔案

最新隨筆

搜索

  •  

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久se精品一区精品二区| 在线激情影院一区| 一区二区三区欧美视频| 一本色道久久综合亚洲精品婷婷 | 激情综合亚洲| 亚洲三级国产| 国产伦精品一区二区三区四区免费| 久久久999| 欧美另类高清视频在线| 久久性色av| 欧美日韩亚洲视频一区| 免费不卡欧美自拍视频| 国产精品欧美一区二区三区奶水| 女人香蕉久久**毛片精品| 欧美性一区二区| 欧美黄色一级视频| 国产综合欧美| 亚洲夜晚福利在线观看| 日韩亚洲欧美一区二区三区| 欧美亚洲三区| 亚洲欧美成人网| 欧美韩国日本综合| 欧美成人免费在线视频| 国产婷婷97碰碰久久人人蜜臀| 亚洲美女在线一区| 亚洲国产中文字幕在线观看| 欧美一区国产二区| 亚洲综合电影| 欧美日韩一区免费| 亚洲日本中文字幕免费在线不卡| 韩国一区二区三区美女美女秀| 一区二区三区国产精华| 亚洲美女毛片| 欧美粗暴jizz性欧美20| 欧美大片在线观看一区| 经典三级久久| 久久琪琪电影院| 麻豆精品传媒视频| 韩国三级在线一区| 久久精品视频网| 麻豆精品精品国产自在97香蕉| 国产欧美一区二区精品秋霞影院| 中文精品视频一区二区在线观看| 正在播放欧美一区| 欧美日韩另类在线| 一区二区高清视频在线观看| 一本色道久久综合亚洲精品按摩 | 久久精品国产综合精品| 国产精品男gay被猛男狂揉视频| 日韩亚洲在线观看| 欧美激情在线有限公司| 一本一本久久a久久精品综合麻豆| 麻豆精品在线视频| 欧美高清你懂得| 亚洲日本欧美| 欧美激情小视频| 99re66热这里只有精品4| 一道本一区二区| 欧美婷婷在线| 亚洲欧美伊人| 久久综合导航| 亚洲清纯自拍| 欧美三级视频在线| 亚洲永久免费精品| 久久综合给合久久狠狠狠97色69| 亚洲高清影视| 欧美日韩精品免费观看视一区二区| 日韩视频在线免费观看| 午夜久久一区| 在线欧美福利| 欧美激情日韩| 亚洲婷婷综合色高清在线| 性视频1819p久久| 黄色日韩网站| 欧美精选午夜久久久乱码6080| 一区二区三区产品免费精品久久75| 午夜精品视频| 在线看片一区| 欧美系列一区| 久久精品五月婷婷| 亚洲精选在线| 久久精品日产第一区二区三区| 在线观看一区| 欧美特黄一区| 久久综合狠狠综合久久激情| 亚洲精品免费在线| 久久久久国产精品午夜一区| 亚洲精品美女在线观看播放| 国产精品久久中文| 你懂的成人av| 午夜在线播放视频欧美| 亚洲第一在线综合网站| 欧美一二三区在线观看| 亚洲日本视频| 国产一区二区三区四区三区四| 欧美精品少妇一区二区三区| 欧美一区二视频在线免费观看| 亚洲日韩欧美一区二区在线| 久久天天狠狠| 亚洲欧美国产精品桃花| 亚洲黄色尤物视频| 国产一区二区三区四区老人| 欧美三级特黄| 欧美99久久| 欧美淫片网站| 亚洲无线观看| 亚洲精品少妇| 欧美激情无毛| 蘑菇福利视频一区播放| 久久成人精品电影| 亚洲一区二区三区精品视频 | 亚洲一区欧美激情| 亚洲人体1000| 蜜臀久久99精品久久久久久9| 性久久久久久久久| av不卡在线观看| 亚洲欧洲另类国产综合| 精品成人在线视频| 国产综合色在线| 国产三级欧美三级| 国产精品日韩欧美一区二区三区| 欧美精品久久久久久久久老牛影院 | 国产精品美女主播| 欧美一区二区三区在线观看视频| 免费在线观看成人av| 久久久另类综合| 国产精品色网| 亚洲欧美视频在线| 香蕉免费一区二区三区在线观看| 欧美激情国产日韩精品一区18| 免费成人性网站| 亚洲国产日韩在线一区模特| 久久久亚洲国产美女国产盗摄| 久久嫩草精品久久久精品| 国产一区二区三区网站| 久久手机精品视频| 亚洲成人在线免费| 亚洲第一主播视频| 亚洲精品乱码久久久久久蜜桃91| 欧美国产日韩精品| 亚洲精品女av网站| 亚洲日本理论电影| 国产伦精品一区二区三区| 先锋资源久久| 91久久综合| 久久久久国产免费免费| 亚洲人www| 国产伦精品一区二区三区视频孕妇 | 国产精品影片在线观看| 免费成人在线观看视频| 宅男在线国产精品| 欧美mv日韩mv国产网站app| 中文av字幕一区| 极品av少妇一区二区| 欧美日韩中文字幕综合视频| 久久不射网站| 一本色道久久综合亚洲91| 国产一区二区三区在线观看免费视频| 浪潮色综合久久天堂| 欧美中文在线视频| 亚洲私人影院在线观看| 亚洲激情一区二区三区| 久久久爽爽爽美女图片| 亚洲欧美日韩国产另类专区| 亚洲精品色婷婷福利天堂| 亚洲第一中文字幕在线观看| 国产一区91精品张津瑜| 国产精品日韩在线播放| 欧美三级第一页| 欧美日韩在线播放三区| 欧美激情aaaa| 欧美精品黄色| 欧美成人r级一区二区三区| 模特精品在线| 欧美精品综合| 国产精品白丝jk黑袜喷水| 国产精品国产a级| 国产精品女人久久久久久| 国产欧美日韩亚洲一区二区三区 | 一区二区高清| 一本一本久久a久久精品综合麻豆 一本一本久久a久久精品牛牛影视 | 久久精品免视看| 噜噜噜91成人网| 欧美日本久久| 国产精品亚洲一区二区三区在线| 国产精品系列在线| 一区一区视频| 亚洲一区二区四区| 蜜桃av综合| 一区二区三区av| 美女国内精品自产拍在线播放| 欧美国产日韩一区二区在线观看 | 亚洲免费成人av电影| 亚洲五月六月| 榴莲视频成人在线观看| 99re热这里只有精品免费视频| 亚洲欧美综合精品久久成人| 欧美高清自拍一区| 国产午夜精品理论片a级探花| 最近看过的日韩成人|