線程的實現原理


線程的實現方式

    實現線程主要有三種方式:(1)使用內核線程實現,(2)使用用戶線程實現(3)使用用戶線程加輕量級進程混合實現。

使用內核線程實現

    內核線程(Kernel-Level Thread,KLT)就是直接由操作系統內核支持的線程,這種線程由內核來完成線程切換,內核通過操縱調度器對線程進行調度,並負責將線程的任務映射到各個處理器上。每個內核線程可以視為內核的一個分身,這種操作系統就有能力同時處理多件事情,支持多線程的內核就叫做多線程內核。

    程序一般不會直接去使用內核線程,而是去使用內核線程的一種高級接口:輕量級進程(Light Weight Process ,LWP),輕量級進程就是我們通常意義上所講的線程,由於每個輕量級進程都由一個內核線程支持,因此只有先支持內核線程,才能有輕量級進程。這種輕量級進程與內核線程之間1:1的關系成為一對一的線程模型。如下圖

 

    由於內核線程的支持,每個輕量級進程都成為一個獨立的調度單元,即使有一個輕量級進程在系統調用中阻塞了,也不會影響整個進程繼續工作,但是輕量級進程具有它的局限性:

    (1)首先,由於是基於內核線程實現的,所以各種線程操作,如創建,析構和同步,都需要進行系統調用。而系統調用的代價相對較高,需要在用戶態和內核態中來回切換。

    (2)其次,每個輕量級進程都需要有一個內核線程的支持,因此輕量級進程要消耗一定的內核資源(如內核線程的棧空間),因此一個系統支持輕量級進程的數量是有限的。

 

使用用戶線程實現

    從廣義上講,一個線程只要不是內核線程,就可以認為是用戶線程(User Thread,UT),因此,從這個定義上來講,輕量級進程也屬於用戶線程,但輕量級進程的實現始終是建立在內核之上的,許多操作都要進行系統調用,效率會受到限制。

    而狹義上的用戶線程指的是完全建立在用戶空間的線程庫上,系統內核不能感知線程存在的實現。用戶線程的建立、同步、銷毀和調度完全在用戶態中完成,不需要內核的幫助。如果程序實現得當,這種線程不需要切換到內核態,因此操作可以是非常快速且低消耗的,也可以支持規模更大的線程數量,部分高性能數據庫中的多線程就是由用戶線程實現的。這種進程與用戶線程之間1:N的關系稱為一對多的線程模型。

    使用用戶線程的優勢在於不需要系統內核支援,劣勢也在於沒有系統內核的支援,所有的線程操作都需要用戶程序自己處理。線程的創建、切換和調度都是需要考慮的問題,而且由於操作系統只把處理器資源分配到進程,那諸如“阻塞如何處理”、“多處理器系統中如果將線程映射到其他處理器上”這類問題解決起來將會異常的困難,甚至不可能完成。因而使用用戶線程實現的程序一般都比較復雜,除了以前在不支持多線程的操作系統中(如DOS)的多線程程序與少數有特殊需求的程序外,現在使用用戶線程的程序越來越少了,Java,Ruby等語言都曾經使用過用戶線程,最終又都放棄使用它。

使用用戶線程加輕量級進程混合實現

    線程除了依賴內核線程實現和完全由用戶程序自己實現之外,還有一種將內核線程與用戶線程一起使用的實現方式。在這種混合實現下,既存在用戶線程,也存在輕量級進程。用戶線程還是完全建立在用戶空間中,因此用戶線程的創建,切換,析構等操作依然廉價,並且可以支持大規模用戶線程並發。而操作系統提供支持的輕量級進程則作為用戶線程和內核線程之間的橋梁,這樣可以使用內核提供的線程調度功能及處理器映射,並且用戶線程的系統調用要通過輕量級線程來完成,大大降低了整個進程被完全阻塞的風險。在這種混合模式中,用戶線程與輕量級進程的數量比是不定,即為N:M的關系。

    許多UNIX系列的操作系統,如Solaris、HP-UX等提供了N:M的線程模式實現。

java線程的實現

    java線程在JDK1.2之前,是基於稱為“綠色線程”(Green Threads)的用戶線程實現的,而在JDK 1.2中,線程模型替換為基於操作系統原生線程模型來實現。因此,在目前的JDK版本中,操作系統支持怎樣的線程模型,在很大程度上決定了java虛擬機的線程是怎樣映射的,這點不同的平台上沒有辦法達成一致,虛擬機規范中也並未限定java線程需要使用哪種線程模型來實現。線程模式只對線程的並發規模和操作成本產生影響,對java程序的編碼和運行過程來說,這些差異都是透明的。

    對於Sun JDK來說,他的Windows版和Linux版都是使用一對一的線程模型來實現的,一條java線程就映射到一條輕量級進程之中,因為Windows和Linux系統提供的線程模型就是就是一對一的。

    而在Solaris平台中,由於操作系統的線程特性可以同時支持一對一(通過Bound Threads或Alternate Libthread實現)及多對多(通過LWP/Thread Based Synchronization實現)的線程模型,因此在Solaris版的JDK中也對應提供了兩個平台專有的虛擬機參數:-XX:+UseL WPSynchronization(默認值)和-XX:+UseBoundThreads來明確指定虛擬機使用哪種線程模型。

    java的線程是通過映射到系統的原生線程上來實現的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM