Unix / Linux 線程的實質


  算法

線程與進程的比較

多線程

概述: 併發

進程是具備必定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位. spa

線程是進程的一個實體,CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程本身基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),可是它可與同屬一個進程的其餘的線程共享進程所擁有的所有資源. 操作系統

一個線程能夠建立和撤銷另外一個線程;同一個進程中的多個線程之間能夠併發執行. 線程

相對進程而言,線程是一個更加接近於執行體的概念,它能夠與同進程中的其餘線程共享數據,但擁有本身的棧空間,擁有獨立的執行序列。 指針

在串行程序基礎上引入線程和進程是爲了提升程序的併發度,從而提升程序運行效率和響應時間。 對象

區別: 進程

程和線程的主要差異在於它們是不一樣的操做系統資源管理方式。進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響,而線程只是一個 進程中的不一樣執行路徑。線程有本身的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等於整個進程死掉,因此多進程的程序要比多線程的程序 健壯,但在進程切換時,耗費資源較大,效率要差一些。但對於一些要求同時進行而且又要共享某些變量的併發操做,只能用線程,不能用進程。 事件

1) 簡而言之,一個程序至少有一個進程,一個進程至少有一個線程.

2) 線程的劃分尺度小於進程,使得多線程程序的併發性高。

3) 另外,進程在執行過程當中擁有獨立的內存單元,而多個線程共享內存,從而極大地提升了程序的運行效率。

4) 線程在執行過程當中與進程仍是有區別的。每一個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。可是線程不可以獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。

5) 從邏輯角度來看,多線程的意義在於一個應用程序中,有多個執行部分能夠同時執行。但操做系統並無將多個線程看作多個獨立的應用,來實現進程的調度和管理以及資源分配。這就是進程和線程的重要區別。

優缺點:

線程和進程在使用上各有優缺點:線程執行開銷小,但不利於資源的管理和保護;而進程正相反。同時,線程適合於在SMP機器上運行,而進程則能夠跨機器遷移。

 

多進程,多線程

概述:

進程就是一個程序運行的時候被CPU抽象出來的,一個程序運行後被抽象爲一個進程,可是線程是從一個進程裏面分割出來的,因爲CPU處理進程的時候是採用時間片輪轉的方式,因此要把一個大個進程給分割成多個線程,例如:網際快車中文件分紅100部分 10個線程 文件就被分紅了10份來同時下載 1-10 佔一個線程 11-20佔一個線程,依次類推,線程越多,文件就被分的越多,同時下載 固然速度也就越快

進程是程序在計算機上的一次執行活動。 你運行一個程序,你就啓動了一個進程。顯然,程序只是一組指令的有序集合,它自己沒有任何運行的含義,只是一個靜態實體。而進程則不一樣,它是程序在某個數 據集上的執行,是一個動態實體。它因建立而產生,因調度而運行,因等待資源或事件而被處於等待狀態,因完成任務而被撤消,反映了一個程序在必定的數據集上 運行的所有動態過程。進程是操做系統分配資源的單位。Windows下,進程又被細化爲線程,也就是一個進程下有多個能獨立運行的更小的單位。線程(Thread)是進程的一個實體,是CPU調度和分派的基本單位。線程不可以獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。

線程和進程的關係是:線程是屬於進程的,線程運行在進程空間內,同一進程所產生的線程共享同一內存空間,當進程退出時該進程所產生的線程都會被強制退出並清除。線程可與屬於同一進程的其它線程共享進程所擁有的所有資源,可是其自己基本上不擁有系統資源,只擁有一點在運行中必不可少的信息(如程序計數器、一組寄存器和棧)

在同一個時間裏,同一個計算機系統中若是容許兩個或兩個以上的進程處於運行狀態,這即是多任務。現代的操做系統幾乎都是多任務操做系統,可以同時管理多個進程的運行。 多任務帶來的好處是明顯的,好比你能夠邊聽mp3邊上網,與此同時甚至能夠將下載的文檔打印出來,而這些任務之間絲絕不會相互干擾。那麼這裏就涉及到並行的問題,俗話說,一心不能二用,這對計算機也同樣,原則上一個CPU只能分配給一個進程,以便運行這個進程。咱們一般使用的計算機中只有一個CPU,也就是說只有一顆心,要讓它一心多用,同時運行多個進程,就必須使用併發技術。實現併發技術至關複雜,最容易理解的是「時間片輪轉進程調度算法」,它的思想簡單介紹以下:在操做系統的管理下,全部正在運行的進程輪流使用CPU,每一個進程容許佔用CPU的時間很是短(好比10毫秒),這樣用戶根本感受不出來CPU是在輪流爲多個進程服務,就好象全部的進程都在不間斷地運行同樣。但實際上在任何一個時間內有且僅有一個進程佔有CPU

若是一臺計算機有多個CPU,狀況就不一樣了,若是進程數小於CPU數,則不一樣的進程能夠分配給不一樣的CPU來運行,這樣,多個進程就是真正同時運行的,這即是並行。但若是進程數大於CPU數,則仍然須要使用併發技術。

Linux中,進行CPU分配是以線程爲單位的,一個進程可能由多個線程組成,這時狀況更加複雜,但簡單地說,有以下關係:

總線程數<= CPU數量:並行運行

總線程數> CPU數量:併發運行

並行運行的效率顯然高於併發運行,因此在多CPU的計算機中,多任務的效率比較高。可是,若是在多CPU計算機中只運行一個進程(線程),就不能發揮多CPU的優點。

 多任務操做系統(Windows)的基本原理是:操做系統將CPU的時間片分配給多個線程,每一個線程在操做系統指定的時間片內完成(注意,這裏的多個線程是分屬於不一樣進程的).操做系統不斷的從一個線程的執行切換到另外一個線程的執行,如此往復,宏觀上看來,就好像是多個線程在一塊兒執行.因爲這多個線程分屬於不一樣的進程,所以在咱們看來,就好像是多個進程在同時執行,這樣就實現了多任務.

分類

根據進程與線程的設置,操做系統大體分爲以下類型:

(1) 單進程、單線程,MS-DOS大體是這種操做系統;

(2) 多進程、單線程,多數UNIX(及類UNIXLINUX)是這種操做系統;

(3) 多進程、多線程,Win32(Windows NT/2000/XP)Solaris 2.xOS/2都是這種操做系統;

(4) 單進程、多線程,VxWorks是這種操做系統。

引入線程帶來的主要好處

(1) 在進程內建立、終止線程比建立、終止進程要快;

(2) 同一進程內的線程間切換比進程間的切換要快,尤爲是用戶級線程間的切換。


===================================================================

用戶級線程 (UserLevel Threads        ULT)

內核級線程 (Kernel Supported threads KST)

  • 內核級線程KST

對於一切的進程,不管是系統進程仍是用戶進程,進程的建立和撤銷,以及I/O操做都是利用系統調用進入到內核,由內核處理完成,因此說在KST下, 全部進程都是在操做系統內核的支持下運行的,是與內核緊密相關的。內核空間實現還爲每一個內核支持線程設置了一個線程控制快,內核是根據該控制快而感知某個 線程是否存在,並加以控制。

優勢:

1.   在多處理器上,內核能夠調用同一進程中的多個線程同時工做;

2.  若是一個進程中的一個線程阻塞了,其餘線程仍然能夠獲得運行;

缺點:對於用戶線程的切換代價太大,在同一個線程中,從一個線程切換到另外一個線程時,須要從用戶態,進入到內核態而且由內核切換。由於線程調度和管理在內核實現。


內核級線程駐留在內核空間,它們是內核對象。有了內核線程,每一個用戶線程被映射或綁定到一個內核線程。用戶線程在其生命期內都會綁定到該內核線程。一旦用 戶線程終止,兩個線程都將離開系統。這被稱做"一對一"線程映射,如圖所示。操做系統調度器管理、調度並分派這些線程。運行時庫爲每一個用戶級 線程請求一個內核級線程。操做系統的內存管理和調度子系統必需要考慮到數量巨大的用戶級線程。您必須瞭解每一個進程容許的線程的最大數目是多少。操做系統爲 每一個線程建立上下文。進程的每一個線程在資源可用時均可以被指派處處理器內核。 

  • 用戶級線程 ULT

用戶進程ULT僅存在於用戶空間中。對於這種線程的建立、撤銷、線程之間的同步和通訊等功能,都無需系統調用來實現。對於同一進程的線程之間切換仍然是不須要內核支持的。因此,內核也會是徹底不會知道用戶級線程的存在。

可是有一點必須注意:設置了用戶級線程的系統,其調度荏苒是以進程爲單位進行的哦。

優勢:

1.  線程切換不須要轉換到內核空間,節省了寶貴的內核空間;

2.  調度算法能夠是進程專用,由用戶程序進行指定;

3.  用戶級線程實現和操做系統無關;

缺點:

1.  系統調用阻塞,同一進程中一個線程阻塞和整個進程都阻塞了。

2.  一個進程只能在一個cpu上得到執行。

 

用戶級線程駐留在用戶空間或模式。運行時庫管理這些線程,它也位於用戶空間。它們對於操做系統是不可見的,所以沒法被調度處處理器內核。每一個線程並不具備 自身的線程上下文。所以,就線程的同時執行而言,任意給定時刻每一個進程只可以有一個線程在運行,並且只有一個處理器內核會被分配給該進程。對於一個進程, 可能有成千上萬個用戶級線程,可是它們對系統資源沒有影響。運行時庫調度並分派這些線程。如同在圖中看到的那樣,庫調度器從進程的多個線程中 選擇一個線程,而後該線程和該進程容許的一個內核線程關聯起來。內核線程將被操做系統調度器指派處處理器內核。用戶級線程是一種"多對一"的線程映射。

  • 混合方式

在不少的操做系統中ULTKLT進行組合,整合了ULTKLT的優勢。


混合線程實現是用戶線程和內核線程的交叉,使得庫和操做系統均可以管理線程。用戶線程由運行時庫調度器管理,內核線程由操做系統調度器管理。在這種實現 中,進程有着本身的內核線程池。可運行的用戶線程由運行時庫分派並標記爲準備好執行的可用線程。操做系統選擇用戶線程並將它映射到線程池中的可用內核線 程。多個用戶線程能夠分配給相同的內核線程。在圖中,進程A在它的線程池中有兩個內核線程,而進程B3個內核線程。進程A的用戶線程23 被映射到內核線程(2)。進程B5個線程,用戶線程12映射到同一個內核線程(3),用戶線程45映射到內核同一個內核線程(5)。當建立新的用戶 線程時,只須要簡單地將它映射到線程池中現有的一個內核線程便可。這種實現使用了"多對多"線程映射。該方法中儘可能使用多對一映射。不少用戶線程將會映射 到一個內核線程,就像您在前面的示例中所看到的。所以,對內核線程的請求將會少於用戶線程的數目。

內核線程池不會被銷燬和重建,這些線程老是位於系統中。它們會在必要時分配給不一樣的用戶級線程,而不是當建立新的用戶級線程時就建立一個新的內核線程,而 純內核級線程被建立時,就會建立一個新的內核線程。只對池中的每一個線程建立上下文。有了內核線程和混合線程,操做系統分配一組處理器內核,進程的線程能夠 在這些處理器內核之上運行。線程只能在爲它們所屬線程指派的處理器內核上運行。

線程上下文

操做系統管理不少進程的執行。有些進程是來自各類程序、系統和應用程序的單獨進程,而某些進程來自被分解爲不少進程的應用或程序。當一個進程從內核 中移出,另外一個進程成爲活動的,這些進程之間便發生了上下文切換。操做系統必須記錄重啓進程和啓動新進程使之活動所須要的全部信息。這些信息被稱做上下 文,它描述了進程的現有狀態。當進程成爲活動的,它能夠繼續從被搶佔的位置開始執行。進程的上下文信息包括:

進程id

指向可執行文件的指針

靜態和動態分配的變量的內存

處理器寄存器

進程上下文的多數信息都與地址空間的描述有關。進程的上下文使用不少系統資源,並且會花費一些時間來從一個進程的上下文切換到另外一個進程的上下文。 線程也有上下文。當線程被搶佔時,就會發生線程之間的上下文切換。若是線程屬於相同的進程,它 們共享相同的地址空間,由於線程包含在它們所屬於的進程的地址空間內。這樣,進程須要恢復的多數信息對於線程而言是不須要的。儘管進程和它的線程共享了很 多內容,但最爲重要的是其地址空間和資源,有些信息對於線程而言是本地且惟一的,而線程的其餘方面包含在進程的各個段的內部。

上下文內容

   

  

指向可執行文件的指針

x

 

x

x

內存(數據段和堆)

x

 

狀態

x

x

優先級

x

x

程序I/O的狀態

x

 

授予權限

x

 

調度信息

x

 

審計信息

x

 

有關資源的信息

文件描述符

/寫指針

x

 

有關事件和信號的信息

x

 

寄存器組

棧指針

指令計數器

諸如此類

x

x


線程本地(且惟一)的信息包括線程id、處理器寄存器(當線程執行時寄存器的狀態,包括程序計數器和棧指針)、線程狀態及優先級、線程特定數 據(thread-specific dataTSD)

線程id是在建立線程時指定的。線程可以訪問它所屬進程的數據段,所以線程能夠讀寫它所屬進程的全局聲明數據。進程中一個線程作出的 任何改動均可以被進程中的全部線程以及主線程得到。在多數狀況下,這要求某種類型的同步以防止無心的更新。線程的局部聲明變量不該當被任何對等線程訪問。 它們被放置到線程棧中,並且當線程完成時,它們便會被移走。

相關文章
相關標籤/搜索