多線程與多進程(2)

原文:http://blog.csdn.net/luoweifu/article/details/46701167
做者:luoweifu
轉載請標名出處linux


線程優先級

如今主流操做系統(如Windows、Linux、Mac OS X)的任務調度除了具備前面提到的時間片輪轉的特色外,還有優先級調度(Priority Schedule)的特色。優先級調度決定了線程按照什麼順序輪流執行,在具備優先級調度的系統中,線程擁有各自的線程優先級(Thread Priority)。具備高優先級的線程會更早地執行,而低優先級的線程一般要等沒有更高優先級的可執行線程時纔會被執行。安全

線程的優先級能夠由用戶手動設置,此外系統也會根據不一樣情形調整優先級。一般狀況下,頻繁地進入等待狀態(進入等待狀態會放棄以前仍可佔用的時間份額)的線程(如IO線程),比頻繁進行大量計算以致於每次都把全部時間片所有用盡的線程更受操做系統的歡迎。由於頻繁進入等待的線程只會佔用不多的時間,這樣操做系統能夠處理更多的任務。咱們把頻繁等待的線程稱之爲IO密集型線程(IO Bound Thread),而把不多等待的線程稱之爲CPU密集型線程(CPU Bound Thread)。IO密集型線程老是比CPU密集型線程更容易獲得優先級的提高。markdown

線程餓死:

在優先級調度下,容易出現一種線程餓死的現象。一個線程餓死是說它的優先級較低,在它執行以前老是有比它優先級更高的線程等待執行,所以這個低優先級的線程始終得不到執行。當CPU密集型的線程優先級較高時,其它低優先級的線程就極可能出現餓死的狀況;當IO密集型線程優先級較高時,其它線程相對不容易形成餓死的善,由於IO線程有大量的等待時間。爲了不線程餓死,調度系統一般會逐步提高那些等待了好久而得不到執行的線程的優先級。這樣,一個線程只要它等待了足夠長的時間,其優先級總會被提高到可讓它執行的程度,也就是說這種狀況下線程始終會獲得執行,只是時間的問題。併發

在優先級調度環境下,線程優先級的改變有三種方式:
1. 用戶指定優先級;
2. 根據進入等待狀態的頻繁程度提高或下降優先級(由操做系統完成);
3. 長時間得不到執行而被提高優先級。post


線程安全與鎖

在多個線程併發執行訪問同一個數據時,若是不採起相應的措施,將會是很是危險的。假設你在工行有一個銀行帳戶,兩張銀聯卡(本身手裏一張,女友手裏一張),裏面有100萬。假設取錢就兩個過程:1.檢查帳戶餘額,2.取出現金(若是要取出的金額 > 帳戶餘額,則取現成功,不然取現失敗)。有一天你要買房想把錢取出來,而此時你女友也想買一輛車(假設大家事先沒有商量)。兩我的都在取錢,你在A號ATM機取100萬,女友在B號ATM機取80萬。這時A號ATM檢查帳戶餘額發現有100萬,能夠取出;而與此同時,同一時刻B號ATM也在檢查帳戶餘額發現有100萬,能夠取出;這樣,A、B都把錢取出來了。ui

100萬的存款取出180萬,銀行就虧大發了(固然你就笑呵呵了……)!這就是線程併發的不安全性。爲避免這種狀況發生,咱們要將多個線程對同一數據的訪問同步,確保線程安全。spa

所謂同步(synchronization)就是指一個線程訪問數據時,其它線程不得對同一個數據進行訪問,即同一時刻只能有一個線程訪問該數據,當這一線程訪問結束時其它線程才能對這它進行訪問。同步最多見的方式就是使用鎖(Lock),也稱爲線程鎖。鎖是一種非強制機制,每個線程在訪問數據或資源以前,首先試圖獲取(Acquire)鎖,並在訪問結束以後釋放(Release)鎖。在鎖被佔用時試圖獲取鎖,線程會進入等待狀態,直到鎖被釋放再次變爲可用。操作系統

二元信號量

二元信號量(Binary Semaphore)是一種最簡單的鎖,它有兩種狀態:佔用和非佔用。它適合只能被惟一一個線程獨佔訪問的資源。當二元信號量處於非佔用狀態時,第一個試圖獲取該二元信號量鎖的線程會得到該鎖,並將二元信號量鎖置爲佔用狀態,以後其它試圖獲取該二元信號量的線程會進入等待狀態,直到該鎖被釋放。.net

信號量

多元信號量容許多個線程訪問同一個資源,多元信號量簡稱信號量(Semaphore),對於容許多個線程併發訪問的資源,這是一個很好的選擇。一個初始值爲N的信號量容許N個線程併發訪問。線程訪問資源時首先獲取信號量鎖,進行以下操做:
1. 將信號量的值減1;
2. 若是信號量的值小於0,則進入等待狀態,不然繼續執行;
訪問資源結束以後,線程釋放信號量鎖,進行以下操做:
1. 將信號量的值加1;
2. 若是信號量的值小於1(等於0),喚醒一個等待中的線程;線程

互斥量

互斥量(Mutex)和二元信號量相似,資源僅容許一個線程訪問。與二元信號量不一樣的是,信號量在整個系統中能夠被任意線程獲取和釋放,也就是說,同一個信號量能夠由一個線程獲取而由另外一線程釋放。而互斥量則要求哪一個線程獲取了該互斥量鎖就由哪一個線程釋放,其它線程越俎代庖釋放互斥量是無效的。

臨界區

臨界區(Critical Section)是一種比互斥量更加嚴格的同步手段。互斥量和信號量在系統的任何進程都是可見的,也就是說一個進程建立了一個互斥量或信號量,另外一進程試圖獲取該鎖是合法的。而臨界區的做用範圍僅限於本進程,其它的進程沒法獲取該鎖。除此之處,臨界區與互斥量的性質相同。

讀寫鎖

讀寫鎖(Read-Write Lock)容許多個線程同時對同一個數據進行讀操做,而只容許一個線程進行寫操做。這是由於讀操做不會改變數據的內容,是安全的;而寫操做會改變數據的內容,是不安全的。對同一個讀寫鎖,有兩種獲取方式:共享的(Shared)和獨佔的(Exclusive)。當鎖處於自由狀態時,試圖以任何一種方式獲取鎖都能成功,並將鎖置爲對應的狀態;若是鎖處於共享狀態,其它線程以共享方式獲取該鎖,仍然能成功,此時該鎖分配給了多個線程;若是其它線程試圖如獨佔的方式獲取處於共享狀態的鎖,它必須等待全部線程釋放該鎖;處於獨佔狀態的鎖阻止任何線程獲取該鎖,不論它們以何種方式。獲取讀寫鎖的方式總結以下:

讀寫鎖的狀態 以共享方式獲取 以獨佔方式獲取
自由 成功 成功
共享 成功 等待
獨佔 等待 等待

 

表 1 :獲取讀寫鎖的方式

 




若是您有什麼疑惑和想法,請在評論處給予反饋,您的反饋就是最好的測評師!因爲本人技術和能力有限,若是本博文有錯誤或不足之處,敬請諒解並給出您寶貴的建議!


原文:http://blog.csdn.net/luoweifu/article/details/46701167
做者:luoweifu 轉載請標名出處

相關文章
相關標籤/搜索