標籤:

對於單核cpu而言,開多線程的目的難倒只能是為了防止阻塞么?

以下是一些單核cpu多線程的疑問,求解答(都指單核)。

1.如果一個進程有n個任務要處理,因為終究是在一個cpu上跑,所以這n個任務在一個線程還是多個線程上跑,執行的總時間是一樣的(多線程,線程切換可能更浪費時間)?

2.是否進程開多線程就能搶到更多的cpu時間,python這種帶GIL的估計是沒戲了,那麼java呢?

3.自己搶到更多cpu,機器上的其它程序不就cpu時間少了么?是因為cpu大部分時間都是空閑的,不怕搶?還是因為在做應用層開發的時候,是不用考慮其它程序能不能搶到cpu時間的。

4.一個進程所有線程能搶到的時間片總和是有最大值嗎?一個線程一次能拿到多長的cpu時間?

綜上,我的最大疑問就是:對於單核cpu而言,開多線程難倒只能防止阻塞么?


(以下回答均針對單核CPU)

問題1概括下來就是很多人喜歡爭論的多線程究竟能不能提高性能?

首先,回答是「能或者不能」。至於「不能」你已經理解了,那麼我來說說為什麼多線程「能」提高性能。要知道一個作業可不總是CPU密集型的,必然穿插著大量的IO調用在其中。而IO的一個特性就是阻塞等待。這個阻塞等待的時間消耗往往是遠遠大於線程切換所消耗的時間的,如果你要訪問10個url獲取介面內容,假如一次http訪問平均阻塞時間大概是1s,那麼你是一個一個的線性訪問快還是10個線程訪問快?相信不用算也知道多線程肯定更快。

最後就可以得出結論,多線程在CPU密集型的作業下的確不能提高性能甚至更浪費時間,但是在IO密集型的作業下則可以提升性能(或者更準確點說叫平均響應時間)。

問題2,進程是最小作業單元,跟進程內開多少線程都無關,CPU對進程的調度是統一的。所以多線程無法促進進程被CPU青睞。python的GIL也是只在CPU密集型的作業下顯現的,通常的業務充斥著大量的IO,所以如果你不是做科學計算,那麼放心大膽的使用多線程吧。

問題3,4,雖說操作系統有自己的調度策略,比如爭搶,時間片輪轉,但是用戶態進程僅僅想通過自身應用級的代碼實現如多線程等手段企圖加大自身的CPU調度權重是不行的,不過自身的線程是可以實現優先順序設置的。也就是說CPU給你整個進程的資源是有限且無法更改的,但是這些資源如何分配你是可以參與的,比如設置線程的優先順序,也只是參與不能主導CPU在某個線程的調度時間,這個是無法控制的。跟當時的系統壓力有關。

綜上,你的問題提到了「阻塞」,這是服務端編程永恆的經典話題。不管是多進程,多線程,還是協程,大多都是致力於解決IO問題,說白了都是怎麼樣把阻塞變成非阻塞的手段。


0. 對於單核cpu而言,開多線程也可能是為了寫著方便好看,說白了就是為了多開個棧,和cpu可能並沒什麼關係。

1. 不一定。看有沒有阻塞IO,也就是看CPU有沒有閑的時候(比如等待讀硬碟)。

2. 不一定,看操作系統的具體調度。

3. 當然怕搶……做應用開發的時候一般會避免在不必要的情況下用很多CPU。把用戶的電腦風扇搞得很響,響應搞得很遲鈍,卻不做什麼事情,用戶一般就把你程序關了……

4. 取決於time interrupt的configuration,每個片一般在ms量級。


對標題大問題來說,不是這樣的。對應用程序來說使用線程主要是方便編程,這個便利性來源於邏輯獨立性,以及共享內存空間。對阻塞而言也有便利性,但往往不得不用的原因來自於運行時系統只提供了線程這一併發/非同步調度機制;同時在多處理器/多核系統中也能享受到性能上提升。


「有些人把多線程的程序設計和多處理器或多核系統聯繫起來. 但是即使程序運行在單處理器上, 也能得到多線程編程的好處. 處理器的數量和並不影響程序結構, 所以不管處理器的個數多少, 程序都可以通過使用多線程得到簡化. 而且, 即使多線程程序在串列化任務上不得不阻塞, 由於某些線程在阻塞的時候還有另一些線程可以運行, 所以多線程程序在單處理器上運行還是可以改善響應時間和吞吐量.

-- 手抄自 UNIX 環境高級編程 第三版 中文版 383頁


單核開多線程只是為了編程方便,屬於類似語法糖的範疇。它在特定領域可以提供較大的編程便利。

不過現在主流的伺服器做法還是幾個核心就開幾個線程或進程。而單線程或進程之內用非同步通信框架以及事件等機制實現多任務。


這裡我說點個人見解,單核cpu多線程對應用程序的響應性能有很大幫助,把UI放入主線程,其他操作(比如圖像生成和資料庫讀寫等)放入子線程,不阻塞UI更新。


推薦閱讀:

linux:多線程進程比單線程進程的性能要差?
多線程無並發用到共享資源,還需要加鎖嗎?
單線程中加鎖代碼的性能如何?
redis為什麼是單線程?在多核處理器下對主存的訪問真的比多線程更有效率?未來有可能改用多線程嗎?
malloc和free是線程安全的嗎,在多線程開發時用這兩個函數應該注意什麼?

TAG:多線程 |