程序與執行緒 翻譯文

2021-08-10 10:06:45 字數 3636 閱讀 5914

所有的內容均來自:
在我們開始討論執行緒,程序,時間片以及各種神奇的「排程機制」之前,先來建立乙個模擬。

我首先要做的就是說明執行緒和程序是如何工作的。我能想到的最好的方式(不涉及實時系統的設計)就是把執行緒和程序想象成一些實際的情形。

程序就像是乙個房子

讓我們用乙個常規的、日常的物品來模擬程序和執行緒——房子。

房子實際上是乙個容器,具有一定的屬性(例如樓面面積,房間數目等等)。

如果你能這樣看待,那麼你就會發現房子不會自己主動去做任何事——它只是乙個被動的物體。這就是程序實際上所擔任的角色。我們待會兒會討論到。

執行緒就像居住者

住在房子裡的人們是活躍的物件——他們使用不同的房間,看電視,做飯,洗澡等等。我們很快就會發現這就是執行緒的行為模式。

單執行緒如果你曾經乙個人生活過,那麼你就會知道這是一種什麼感覺——你知道,你可以在任何時候在家裡做任何你想做的事,因為房子裡沒有其他人。如果你想開啟立體聲音響,使用洗手間,吃晚餐,隨便你,你只要繼續做就行了。

多執行緒當你把另乙個人加入房子時,事情會發生戲劇性的變化。假設你結婚了,所以現在你的配偶也住在那裡。你不能在任何乙個特定的時間進入洗手間,你需要先檢查一下,確保你的配偶不在裡面!

現在,把幾個孩子扔到一起,突然之間事情變得有趣多了。

回到程序和執行緒

就像房子佔據了房地產的一部分一樣,程序也會佔據一定的記憶體。就像房子的住戶可以自由進入任何他們想要的房間一樣,乙個程序的執行緒都可以訪問這個記憶體。如果乙個執行緒分配了一些東西(媽媽出去買了乙個遊戲),所有其他的執行緒都能立即訪問它(因為它存在於公共位址空間-它在房子裡)。同樣,如果程序分配記憶體,那麼這個新記憶體也可以用於所有執行緒。這裡的技巧是,確認記憶體是否應該對程序中的所有執行緒都可用。如果是,那麼您需要讓所有執行緒同步它們對它的訪問。如果不是,那麼我們假設它是特定於特定執行緒的。在這種情況下,因為只有該執行緒才能訪問它,所以我們可以假定不需要同步-執行緒不會自行啟動!

正如我們從日常生活中所知道的,事情並不那麼簡單。現在我們已經了解了基本特性(要點:所有內容都是共享的),讓我們來看看事情變得更有趣的地方,以及為什麼。

下圖顯示了我們將代表執行緒和程序的方式。程序是圓,表示「容器」概念(位址空間),三個squigley lines(不知道是什麼)是執行緒。你會在書中看到這樣的圖表。

相互排斥

如果你想洗個澡,而且有人已經在用浴室,你就得等著。執行緒是如何處理這個的?

它用的是一種叫做互斥的操作。它幾乎意味著你所想的-當涉及到特定的資源時,許多執行緒是互斥的。

如果你正在洗澡,你想要獨佔浴室。要做到這一點,你通常會進入浴室並把門從裡面鎖起來。任何想使用浴室的人都會被鎖上的。當你完成任務時,你會開啟門,讓其他人進入。

這就是執行緒所做的。執行緒使用乙個名為互斥的物件(相互排斥的縮寫)。這個物件就像門上的鎖-一旦執行緒擁有互斥鎖,沒有其他執行緒可以獲得互斥鎖,直到擁有的執行緒釋放(解鎖)它。就像門鎖一樣,等待獲得互斥鎖的執行緒將被禁止。

互斥鎖和門鎖的另乙個有趣的相同點是互斥鎖實際上是乙個「諮詢」鎖。如果乙個執行緒不符合使用互斥鎖的約定,那麼保護就沒有用了。在我們的房子比喻中,這就像有人通過牆壁闖進廁所,無視了門和鎖的約定。

優先順序如果浴室現在鎖著,有許多人在等著使用它,那該怎麼做?顯然,所有的人都坐在外面,等著在浴室裡的人出去。真正的問題是,「當門開啟時會發生什麼?誰能下乙個進入?「

你會認為,讓等了最長的時間得那個成為下乙個是「公平的」。或者,讓最年長的人成為下乙個是「公平」的。或者最高的。或者最重要的。有許多方法可以確定什麼是「公平」。

我們通過執行緒的兩個因素來解決這個問題:優先順序和等待長度。

假設兩個人同時出現在(上鎖的)衛生間的門前。其中一人有乙個緊迫的事情(他們開會已經很晚了),而另乙個卻沒有。讓那個時間緊迫的人下一次進去,是不是很有道理呢?當然會了。唯一的問題是你如何決定誰更「重要」。這可以通過分配優先順序來完成(讓我們使用乙個像中微子(neutrino)這樣的數字,是最低的可用優先順序,255是這個版本中的最高值)。房子裡有緊迫事情的人將被給予更高的優先權,而那些不被優先考慮的人將被給予較低的優先權。

和執行緒一樣。執行緒繼承其父執行緒的排程演算法,但可以呼叫pthread_setschedparam()來更改其排程策略和優先順序(如果它有許可權這樣做)。

如果有多個執行緒等待,並且互斥鎖被解鎖,我們將把互斥鎖給予等待執行緒中最高優先順序的那個。但是,假設兩個人都具有相同的優先順序。現在你要做什麼?好吧,在這種情況下,讓等待最長的人下乙個或許是「公平的」。這不僅是「公平的」,而且也是在核心所做的。在一堆執行緒等待的情況下,我們首先是按優先順序等級來決定,其次是等待長度。

互斥量肯定不是我們將遇到的唯一的同步物件。讓我們看看其他的。

訊號量讓我們從浴室搬到廚房,因為這是乙個在社會上可以接受同時容納乙個人以上的地點。在廚房裡,你可能不想讓每個人都在裡面。事實上,你可能想要限制你的廚房裡所能容納的人數(太多的廚師,等等)。

假設你不想同時擁有兩個以上的人。你能用互斥體來實現嗎?這不是我們定義的。為什麼不呢?這實際上是乙個非常有趣的問題。讓我們把它分成幾個步驟。

數量為1的訊號量

浴室可以有兩種情況中的一種,兩種狀態相互聯絡(with two states that go hand-in-hand with each other):

沒有其他的組合是可能的-當房間裡沒人的時候不能上鎖(不然我們怎麼解鎖?),而且當有人在房間裡時不能解鎖(他們怎麼保證他們的隱私?)。這是乙個訊號量的示例,其計數為1-最多只能有乙個人在該房間,或者乙個執行緒使用訊號量。

這裡的關鍵(key)(請原諒雙關語)是我們描述鎖的方式。在典型的浴室鎖中,你可以鎖定和解鎖它只有從內部-沒有外部可訪問的鑰匙。實際上,這意味著互斥物件的所有權是乙個原子操作-在獲取互斥鎖的過程中,沒有可能有其他執行緒得到它,結果是你一直擁有互斥鎖。在我們的房子比喻中,這是不太明顯的,因為人模擬計算機聰明太多(smarter than ones and zeros)。

數量大於1的訊號量

現在,控制我們想要多少人在廚房裡-把兩個鑰匙掛在門外,這就變成了一件簡單的事情!廚房總是鎖著的。當有人想走進廚房時,他們會發現門外有一把鑰匙。如果是的話,他們就帶著它,開啟廚房的門,進去,用鑰匙鎖上門。

因為進入廚房的人在廚房的時候一定要帶鑰匙,所以我們可以通過限制門上的鑰匙的數量來直接控制進入廚房的人數。

對於執行緒,這就需要通過訊號量來完成了。「普通」訊號量就像乙個互斥體一樣工作-你要麼擁有互斥量,在這種情況下,你可以訪問資源,或者你沒有,在這種情況下,你沒有訪問許可權。我們剛才在廚房描述的訊號量是乙個計數訊號,它保持計數的記錄(執行緒所允許的keys數量)。

互斥的訊號量

我們只是問了乙個問題「你能用乙個互斥量來做嗎?」關於用計數實現乙個鎖,答案是否定的,反過來呢?我們能用訊號量作為互斥量嗎?

是的。事實上,在某些作業系統中,這正是他們所做的-他們沒有互斥鎖,只有訊號量!那麼,為什麼要麻煩互斥鎖呢?

要回答這個問題,看看你的洗手間。你的房子的建造者是如何實現「互斥」的?我猜你沒有掛在牆上的鑰匙!

互斥鎖(mutexes)是乙個「特殊用途」訊號量。如果您希望乙個執行緒在特定的**段中執行,那麼互斥鎖是迄今為止最有效的實現。

這篇文章真的可謂是生動有趣,把執行緒和程序用了生活中的比喻來描述,很是深刻。原文中的描述雖然簡單,但有些單詞還是有些拿不準,我都打出來了,甚至有一些描述有些生硬,如有錯誤,請指出。

翻譯文章後再來看翻譯文章

前幾天在倉庫中找到一本關於黑客的英文版的文章,看了一下覺得也不太難,又想到老師說要提高一下英文閱讀能力,於是便想 要是把這文章翻譯了是不是能更快的提高閱讀能力呢?因為單純的閱讀並不能夠把全部精力放到文章中,如果說你是為了某件事 某個目的來讀的話,想必精力能高度集中。事實證明效果很好,雖然有些花費時間...

候選翻譯文章列表 示範

本翻譯文章列表持續更新中,大家有好的文章記得告訴我,我會把它們放入該列表的。講的透徹,不一定要有多少 但能夠把問題講清楚 不一定要涉及很難的技術,對於一些基礎的東西我們可能更需要些,前段時間園子裡有人反映發布的文章太難了,因此我覺得一些打基礎文章的教材如果寫得很詳細,可以翻出來給初學者看看 不一定非...

候選翻譯文章列表 示範

本翻譯文章列表持續更新中,大家有好的文章記得告訴我,我會把它們放入該列表的。個人對於好文章的一些理解 講的透徹,不一定要有多少 但能夠把問題講清楚 不一定要涉及很難的技術,對於一些基礎的東西我們可能更需要些,前段時間園子裡有人反映發布的文章太難了,因此我覺得一些打基礎文章的教材如果寫得很詳細,可以翻...