1.1 出現的歷史
人類常常想著要建一個比以前所有偉大項目更棒的新計畫。吉薩的胡夫金字塔是最大,杜拜的哈利法塔是最高,而中國的萬里長城是最長。
但要組織這些項目的工作非常困難。如果要建一個高一倍的金字塔,那需要八倍多的石頭。所以,要麼提高採石場的生產力,要麼開更多的採石場。
還需要找到八倍多的工程師,可能還需要開設工程學校,標準化圖紙、幾何、書寫系統。總之,這可真是一個大挑戰...
自從建造金字塔的數千年以來,事情沒有改變——人們一直在想如何用更少的時間做更多的工作。而當電腦被發明出來後,這個問題就由人類最聰明的頭腦在思考了。
怎麼讓程序運行速度提高十倍?看似奇怪的問題——如果處理器已經在以最高速度運行,那麼大概是不可能的。但我不是隨便提到人類最聰明的頭腦,他們分析了所有程序的運行,得出結論,有三個重要方向可以提升。
消除空閒時間
原來,程序大部分時間都是空轉。總是等著什麼:數據要從一個記憶體位置拷貝到另一個,從硬碟下載到記憶體,等伺服器回應請求,或用戶輸入等等。
所有這些任務不是由中央處理器執行的,而是由記憶體控制器、硬碟等執行的。而在這段時間,中央處理器本來可以被用來執行一些有用的工作。於是產生了在一個處理器中不只運行一個指令流(thread),而是多個的想法。
比如說,一個執行流在等待用戶輸入,第二個從網絡下載東西,第三個處理數據,第四個在螢幕上繪製圖像。這個想法隨後演變成為異步任務和協程,但這是後話。
更多的程式
程式空轉80%的時間,當然這不好。另一方面,也不可能用我們的新方法重寫所有的程式。也許這個問題可以用其他方式解決——可以在電腦上同時運行幾個程式。
這樣操作系統就會監控程式的運行情況,如果一個程式空轉,就把它的執行時間交給另一個程式。這種切換每秒發生數十次,用戶根本不會察覺切換——在他看來,程式是同時進行的。
更多的處理器
同時執行程式是很厲害,但如果程式很多,空轉的時間卻不多呢?沒有空轉,就沒有高效利用。比如說,我們有十個程式在計算東西,或者有資源密集型的遊戲和其他東西同時運行。
解決這個問題的辦法是把處理器中增加多個處理器。為了避免混淆,他們開始被稱為核心。現在我們有了多核處理器,這些核心(子處理器)可以同時運行數十個程式。
趣聞!處理器的核心數量
到目前為止,伺服器處理器可以擁有64到256個核心,在某些專用情況下甚至更多。例如,第四代AMD EPYC處理器提供最多96個核心,而IBM POWER10芯片可以有240個核心。用戶端處理器也有很大進步:高性能桌面CPU,如AMD Threadripper,可以擁有最多64個核心,而更常見的型號通常有6到16個核心。
下一步呢?還有地方可以探索!首先,一塊伺服器主板可以安裝多個處理器,比如兩個甚至四個。其次,伺服器可以合併成10-20台伺服器架。伺服器架可以集成到數據中心,那裡有數千個這樣的架子。
分散式系統和微服務架構已成為現代軟體開發的常見實踐。許多大公司,如Google、Amazon、Netflix,甚至是較小的企業,都使用分散式系統來處理大量數據,確保高可用性和可伸縮性。這些系統允許有效利用多台服務器的資源,作為一個整體工作,這大大提高了應用程序的性能和可靠性。
1.2 優勢
多執行緒,或者程式內部任務的同時執行,提供了幾個關鍵優勢,這些優勢可以顯著改善軟體性能和效率。讓我們看看多執行緒的主要優勢。
1. 提高性能和執行速度
任務的並行執行:多執行緒允許同時執行多個任務,這對需要執行獨立操作的程式特別有用。這可以加快程序的執行,因為任務是並行執行的,利用了所有可用的處理器資源。
利用多核處理器:現代處理器擁有多個核心,多執行緒允許完全利用這些核心的能力,通過在不同核心上分配執行緒來並行執行任務。
2. 改善用戶回應和交互
背景任務:多執行緒允許在背景中執行長時間或資源密集型操作,同時保持負責用戶介面的主執行緒具有回應性。這改善了用戶體驗,因為在執行繁重任務時介面不會被鎖住。
非同步操作:用戶交互和事件處理可以與主要任務的執行並行發生,使應用程式更具回應性和效率。
3. 系統資源的有效使用
優化資源:多執行緒允許更有效地使用系統資源,如處理器時間和記憶體。對於伺服器和高性能計算系統來說,這尤其重要,因為多執行緒允許同時處理大量請求和任務。
輸入輸出管理:多執行緒應用程序可以更有效地管理輸入輸出任務(例如,網絡操作,文件的讀寫),因為執行緒可以在等待某個輸入輸出操作完成時執行其他任務。
4. 支持多任務
多任務:多執行緒允許在一個進程中同時執行多個任務,這簡化了需要多任務的應用程序的開發,如web伺服器、資料庫和實時應用程序。
資料的並行處理:在與大數據處理相關的任務中,多執行緒允許將數據分割成塊來並行處理,這大大加快了任務的執行。
多執行緒的使用例子
網頁伺服器:多執行緒允許網頁伺服器同時處理許多客戶端請求,提高伺服器的性能和可擴展性。
圖形用戶界面(GUI):在具有圖形介面的應用程序中,多執行緒允許在背景中執行長時間的計算,保持介面可回應。
科學計算:多執行緒用於科學計算中的並行資料處理,這樣可以大大加快複雜計算任務的執行。
遊戲和模擬:在遊戲中,多執行緒允許同時處理物理、圖形、聲音和用戶的行為,改善性能和現實感。
1.3 正確的名詞
「多執行緒」這個名詞有些爭議。它由兩個詞組成:「多」和「執行緒」,似乎在暗示在程式內有許多「指令執行流」,在做某些事情。
這是個不錯的類比,但在英文(原始)文獻中,來描述並行執行操作的術語是「線程」(thread)。因此,多執行緒在那裏叫做multi-threading。
這可以被視為一個小誤解——誰會在意不同的術語在另一種語言中的翻譯,如果不是在程式設計中開始積極使用像stream這樣的東西,而這個東西除了「流」沒有別的翻譯。
因此,現在在俄語術語中有些困惑,這有兩個解決方案:
-
Thread(線程)翻譯為「指令流」。 Stream(流)翻譯為「資料流」。
另一方面,許多程式設計師開始直接在不翻譯的情況下使用英語術語:
-
Thread(線程)被唸作「thr之音」而multi-threading被叫做「malti-thr之音」。 Stream(流)被唸作「stream」。
Thread常被稱為線程,但「多線程」這個術語並沒有流行。因此,在對話中經常同時使用「線程」和「多執行緒」。
使用大量借來的術語使得語言更加豐富,賦予詞語新的意義,並簡化與其他國家同事的交流。我完全支持這種方法。
GO TO FULL VERSION