Windows編程--線程和核心對象的同步-信標(訊號量)核心對象

來源:互聯網
上載者:User

信標核心對象用於對資源進行計數。它們與所有核心對象一樣,包含一個使用數量,但是它們也包含另外兩個帶符號的3 2位值。

一個是最大資源數量,用於標識信標能夠控制的資源的最大數量。

一個是當前資源數量,用於標識當前可以使用的資源的數量。

(FangSH注:有些書稱之為資訊量核心對象)

為了正確地說明這個問題,讓我們來看一看應用程式是如何使用信標的。比如說,我正在開發一個伺服器處理序,在這個進程中,我已經分配了一個能夠用來存放客戶機請求的緩衝區。我對緩衝區的大小進行了寫入程式碼,這樣它每次最多能夠存放5個客戶機請求。如果5個請求尚未處理完畢時,一個新客戶機試圖與伺服器進行聯絡,那麼這個新客戶機的請求就會被拒絕,並出現一個錯誤,指明伺服器現在很忙,客戶機應該過些時候重新進行聯絡。

當我的伺服器處理序初始化時,它建立一個線程池,裡麵包含5個線程,每個線程都準備在客戶機請求到來時對它進行處理。

開始時,沒有客戶機提出任何請求,因此我的伺服器不允許線程池中的任何線程成為可調度線程。但是,如果3個客戶機請求同時到來,那麼線程池中應該有3個線程處於可調度狀態。使用信標,就能夠很好地處理對資源的監控和對線程的調度,最大資源數量設定為5,因為這是我進行硬式編碼緩衝區的大小。當前資源數量最初設定為0,因為沒有客戶機提出任何請求。當客戶機的請求被接受時,當前資源數量就遞增,當客戶機的請求被提交給伺服器的線程池時,當前資源數量就遞減。

 

信標的使用規則如下:

• 如果當前資源的數量大於0,則發出信標訊號。

• 如果當前資源數量是0,則不發出信標訊號。

• 系統決不允許當前資源的數量為負值。

• 當前資源數量決不能大於最大資源數量。

 注意

當使用信標時,不要將信標對象的使用數量與它的當前資源數量混為一談。

 

下面的函數用於建立信標核心對象:

 

HANDLE CreateSemaphore(
PSECURITY_ATTRIBUTE psa,// 安全屬性指標
LONG lInitialCount, //當前可用資源初始值,這個值必須大於等於0,小於等於lMaximumCount
LONGlMaximumCount, //最大可用的資源數,這個值必須大於0
PCTSTRpszName); //對象名指標

 

 

Psa和pszName兩個參數核心對象的安全屬性和,核心對象的命名。

MaximumCount參數用於告訴系統,應用程式處理的最大資源數量是多少。由於這是個帶符號的32位值,因此最多可以擁有2 147 483 647個資源。

lInitialCount參數用於指明開始時(當前)這些資源中有多少可供使用。

通過調用OpenSemaphore函數,另一個進程可以獲得它自己的進程與現有信標相關的控制代碼:

 

HANDLE OpenSemaphore(
DWORDfdwAccess,
BOOL bInheritHandle,
PCTSTRpszName);

 

 

當我的伺服器處理序初始化時,沒有任何客戶機請求,因此我調用下面這個CreateSemaph ore函數:

HANDLE hsem =CreateSemaphore(NULL, 0, 5, NULL);

 

該函數建立了一個信標,其最大資源數量為5,但是開始時可以使用的資源為0因此不發出信標訊號。等待信標的所有線程均進入等待狀態。

 (FangSH註:資源的訪問,當前可用資源計數就會減1,只要當前可用資源計數是大於0的,就可以發出訊號量訊號。
但是當前可用計數減小到0時則說明當前佔用資源的線程數已經達到了所允許的最大數目,不能在允許其他線程的進入
此時的訊號量訊號將不發出信標訊號.

)

通過調用ReleaseSemaphore函數,線程就能夠對信標的當前資源數量進行遞增:

 

BOOL ReleaseSemaphore( 
HANDLE hsem, //訊號量控制代碼
LONGlReleaseCount, // 計數遞增數量
PLONGplPreviousCount); // 先前計數

 

 

該函數只是將lReleaseCount 中的值添加給信標的當前資源數量。一般情況下,為lReleaseCount參數傳遞1。但是,不一定非要傳遞這個值。我常常傳遞2或更大的值。該函數也能夠在它的* plPreviousCount中返回當前資源數量的原始值。實際上幾乎沒有應用程式關心這個值,因此可以傳遞NULL,將它忽略。

 

總結:

WaitForSingleObject()WaitForMultipleObjects()主要用在試圖進入共用資源的線程函數入口處,主要用來判斷訊號量的當前可用資源計數是否允許本線程的進入。只有在當前可用資源計數值大於0時,被監視的訊號量核心對象才會得到通知。

 

函數CreateSemaphore的psa為NULL,lInitialCount為當前可用資源初始值,lMaximumCount為最大可用資源數,pszName為名字。當lInitialCount的值等於0時,信標對象處於無訊號狀態,這時核心將調用等待函數的線程置於睡眠狀態,如果lInitialCount的值大於0,信標對象處於有訊號狀態,這時核心將調用等待函數的線程置於運行狀態,並將信標對象的當前可用資源數減1

函數ReleaseSemaphore的hsem為信標對象的控制代碼,lReleaseCount為要釋放的資源數,plPreviousCount返回原來可用資源數,調用此函數將當前可用資源數加上lReleaseCount的值。當一個線程訪問完可用資源後,應該調用ReleaseSemaphore函數使當前可用資源數遞增。要在不同進程中訪問同一信標對象,調用CreateSemaphore函數並傳遞信標對象的名稱,得到已經在其它進程建立的信標對象的控制代碼。另外有一點要注意,等待函數預設將信標對象的當前可用資源數減1,但線程可能一次使用多個資源,這就可能出現問題了。為避免問題出現,應該遵守一個線程只使用一個資源的原則。

 

FangSH 2011-01-04

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.