臨界區(criticalSection)
又稱阻塞,它能夠使一段代碼只由一個線程來執行,其它線程被擋在這段代碼之外,直到第一個線程執行完代碼。臨界區的使用主要涉及如下API函數:
initializeCriticalSection(), 在臨界區首次使用之前,用此函數進行初始化。
deleteCreticalSection(), 在臨界區不再使用之前,用此函數釋放臨界區。
enterCriticalSection(), 在初始化之后,用此函數進入阻塞。
leaveCriticalSection(), 在代碼執行完之后,用此函數解除阻塞。
互斥(mutex)
互斥比較類似阻塞,關鍵在于互斥可以跨進程的線程同步,很多只允許應用程序運行一次的實例就是用互斥方法來實現的。互斥用到以下的API函數:
createMutex(), 創建互斥對象。
releaseMutex(), 解除互斥關系。
互斥的一般使用流程:
首先createMutex創建互斥對象,然后waitForSingleObject進入互斥環境,當用到同步的代碼執行完成后,用releaseMutex解除互斥關系,當所有線程訪問完后,調用
closeHandle方法釋放互斥對象。
waitForSingleObject()函數來防止其它線程進入同步區域的代碼。
function waitforsingleobject(hHandle: Thandle; dwMilliseconds: DWORD): DWORD; stdcall;
這個函數可以使當前線程在dwmilliseconds指定的時間內睡眠,直到hHandle參數指定的對象進入發信號狀態為止。一個互斥對象不再被線程擁有時,它就進入發信號狀態
當一個進程要終止時,它就進入發信號狀態。dwmilliseconds參數可以設為0,這意味著只檢查hhandle參數指定的對象是否處理發信號狀態,而后立即返回。dwmilliseconds參數設為INFINITE,表示如果信號不出現將一直等下去。
waitForSingeObject()使用的返回值及其含義:
WAIT ABANDONED
指定的對象是互斥對象,并且擁有這個互斥對象的線程在沒有釋放此對象之前就已終止。此時就稱互斥對象被拋棄。這種情況下,這個互斥對象歸當前線程所有,并把它設為不發信號狀態。
WAIT OBJECT 0
指定的對象處于發信號狀態
WAIT TIMEOUT
等待的時間已過,對象仍然是非發信號狀態
當一個互斥對象不再被一個線程所擁有,它就處于發信號狀態。此時首先調用waitForsingleobject()的線程就成為該互斥對象的擁有者,此互斥對象設為不發信號狀態。當線程調用releaseMutex()并傳遞一個互斥對象的句柄作為參數時,這種擁有關系就被解除,互斥對象重新進入發信號狀態。除waitforsingleobject()外,還可以使用waitformultipleobject()和msgwaitformultipleobject(),它們可以等待幾個對象變為發信號狀態。
信號量(semaphore)
另一種使線程同步的技術是使用信號量對象。它是在互斥的基礎上建立的。但信號量增加了資源計數的功能,預定數目的線程允許同時進入要同步的代碼。用
createSemaphore()來創建一個信號量對象,其聲明如下:
function createsemaphore(lpSemaphoreAttributes: pSecurityAttributes;
lInitalCount, lMaximunCount: longint; lpName: pchar): Thandle; stdcall;
和createmutex()一樣,createsemaphore()的第一個參數也是一個指向TsecurityAttributes記錄的指針,此參數的缺少值可以設為nil。lInitialcount參數用來指定個信號量的初始計數
值,這個值必須在0和lMaximumcount之間。此參數大于0 ,就表示信號量處于發信號狀態。當調用waitforsingleobject()時,此計數值就減1。當調用releasesemaphore()時,此計數值加1。參數lMaximumcount指定計數值的最大值。如果這個信號量代表某種資源,那么這個值代表可用資源總數。參數lpName用于給出信號量對象的名稱。類似于createmutex()的lpName參數。
releaseSemaphore()的聲明:
function releaseSemaphore(hsemaphore: Thandle; lreleasecount: longint;
lppreviouscount: pointer): bool; stdcall;
ireleasecount參數用于指定每次使計數值加多少。如果參數lppreviouscount不為nil,原有的計數值將存儲在lppreviouscount里。信號量對象并不屬于某個線程。記住,最后一定要調用colsehandle()來釋放由createsemaphore()創建的信號量對象的句柄。
posted on 2009-08-19 09:37
Bluesea 閱讀(1285)
評論(0) 編輯 收藏 引用 所屬分類:
C/C++