學習筆記-進程-線程-協程

本文目的

前兩章節已經詳細的向大家介紹過進程(詳見 )和線程(詳見 )。本文旨在向大家詳細的介紹進程-線程-協程的基本關係。

基本概念

進程

進程是具有一定獨立功能的程序在某個數據集合上的一次運行過程,進程是系統進行資源分配和調度的一個獨立單位。每個進程都有自己的獨立內存空間,不同進程通過進程間通信來通信。由於進程佔據獨立的內存,所以上下文進程間的切換開銷(棧、寄存器、虛擬內存、文件句柄等)比較大,但相對比較穩定安全。

線程

線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源。線程間通信主要通過共享內存。上下文切換很快,資源開銷較少,但相比進程不夠穩定容易丟失數據。

協程

協程是一種用戶態的輕量級線程,協程的調度完全由用戶控制

。與子例程一樣,協程也是一種程序組件。相對子例程而言,協程更為一般和靈活,但在實踐中使用沒有子例程那樣廣泛。協程擁有自己的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,直接操作棧則基本沒有內核切換的開銷,可以不加鎖的訪問全局變量,所以上下文的切換非常快。

並行與併發

併發

併發,在操作系統中,是指一個時間段中有幾個程序都處於已啟動運行到運行完畢之間,且這幾個程序都是在同一個處理機上運行,但任一個時刻點上只有一個程序在處理機上運行

並行

並行是指"並排行走"或"同時實行或實施"。在操作系統中是指,一組程序按獨立異步的速度執行,不等於時間上的重疊(同一個時刻發生)。要區別併發。併發是指:在同一個時間段內,兩個或多個程序執行,有時間上的重疊(宏觀上是同時,微觀上仍是順序執行)

併發和並行從宏觀上來講都是同時處理多路請求的概念。但併發和並行又有區別,並行是指兩個或者多個事件在同一時刻發生;而併發是指兩個或多個事件在同一時間間隔內發生。 併發的設計使到併發執行成為可能,而並行是併發執行的其中一種模式。

學習筆記-進程-線程-協程

並行與併發

簡單理解

進程

進程的出現是為了更好的利用CPU資源使到併發成為可能 假設有兩個任務A和B,當A遇到I/O操作,CPU默默的等待任務A讀取完操作再去執行任務B,這樣無疑是對CPU資源的極大的浪費。於是人們就在想如果在任務A讀取數據時,讓任務B執行,當任務A讀取完數據後,再切換到任務A執行。注意關鍵字切換,那麼這就涉及到了狀態的保存,狀態的恢復,加上任務A與任務B所需要的系統資源(內存,硬盤,鍵盤等等)是不一樣的。自然而然的就需要有一個東西去記錄任務A和任務B分別需要什麼資源,怎樣去識別任務A和任務B等等。於是進程就被髮明出來了。通過進程來分配系統資源,標識任務。如何分配CPU去執行進程稱之為調度,進程狀態的記錄,恢復,切換稱之為上下文切換。進程是系統資源分配的最小單位,進程佔用的資源有:地址空間,全局變量,文件描述符,各種硬件等等資源。

線程

線程的出現是為了降低上下文切換的消耗,提高系統的併發性,並突破一個進程只能幹一樣事的缺陷,使到進程內併發成為可能。假設,一個文本程序,需要接受鍵盤輸入,將內容顯示在屏幕上,還需要保存信息到硬盤中。若只有一個進程,勢必造成同一時間只能幹一樣事的尷尬(當保存時,就不能通過鍵盤輸入內容)。若有多個進程,每個進程負責一個任務,進程A負責接收鍵盤輸入的任務,進程B負責將內容顯示在屏幕上的任務,進程C負責保存內容到硬盤中的任務。這裡進程A,B,C間的協作涉及到了進程通信問題,而且有共同都需要擁有的東西—文本內容,不停的切換造成性能上的損失。若有一種機制,可以使任務A,B,C共享資源,這樣上下文切換所需要保存和恢復的內容就少了,同時又可以減少通信所帶來的性能損耗,那就好了。是的,這種機制就是線程。線程共享進程的大部分資源,並參與CPU的調度, 當然線程自己也是擁有自己的資源的,例如,棧,寄存器等等。 此時,進程同時也是線程的容器。線程也是有著自己的缺陷的,例如健壯性差,若一個線程掛掉了,整一個進程也掛掉了,這意味著其它線程也掛掉了,進程卻沒有這個問題,一個進程掛掉,另外的進程還是活著。

協程

協程通過在線程中實現調度,避免了陷入內核級別的上下文切換造成的性能損失,進而突破了線程在IO上的性能瓶頸。 當涉及到大規模的併發連接時,例如一萬連接。以線程作為處理單元,系統調度的開銷還是過大。當連接數很多,需要大量的線程來幹活,可能大部分的線程處於Ready狀態, 系統會不斷地進行上下文切換。既然性能瓶頸在上下文切換,那解決思路也就有了,在線程中自己實現調度,不陷入內核級別的上下文切換。

總結:

進程出現優化了CPU的調度。CPU(單核)與進程對應關係為一對一。

線程出現優化了進程的調度。進程與線程對應關係為一對多。

協程出現優化了線程的調度。線程與協程對應關係為一對多。

學習筆記-進程-線程-協程

進程-線程-協程關係

拓展:

(1)單CPU中進程只能是併發,多CPU計算機中進程可以並行。

(2)單CPU單核中線程只能併發,單CPU多核中線程可以並行。

(3) 無論是併發還是並行,使用者來看,看到的是多進程,多線程。

區別與聯繫

區別

1. 操作級別:進程,線程是操作系統級的,協程是語言級的。

2. 機制:進程,線程是同步機制,而協程則是異步機制。

3. 空間:進程擁有自己獨立的堆和棧,既不共享堆,亦不共享棧。線程擁有自己獨立的棧和共享的堆,共享堆,不共享棧。協程和線程一樣共享堆,不共享棧。

4. 屬性:線程作為調度和分配的基本單位,進程作為擁有資源的基本單位。

5. 資源分配:進程是擁有資源的一個獨立單位,線程不擁有系統資源,但可以訪問隸屬於進程的資源。進程所維護的是程序所包含的資源(靜態資源), 如:地址空間,打開的文件句柄集,文件系統狀態,信號處理handler等;線程所維護的運行相關的資源(動態資源),如:運行棧,調度相關的控制信息,待處理的信號集等;

6. 系統開銷:在創建或撤消進程時,由於系統都要為之分配和回收資源,導致系統的開銷明顯大於創建或撤消線程時的開銷。但是進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響,而線程只是一個進程中的不同執行路徑。線程有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個進程死掉就等於所有的線程死掉,所以多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差一些。

7. 耗時:線程上下文切換比進程上下文切換耗時更短。線程創建和銷燬所需要的時間比進程小很多。

8. 屬性:線程有自己的私有屬性TCB,線程id,寄存器、硬件上下文,而進程也有自己的私有屬性進程控制塊PCB,這些私有屬性是不被共享的,用來標示一個進程或一個線程的標誌

9. 使用場景:IO密集型一般使用多線程或者多進程,CPU密集型一般使用多進程。

聯繫

(1)協程是一種用戶態的輕量級線程,線程是輕量級的進程

(2)一個進程包含多個線程,一個線程包含多個協程。

(3)同一個進程中可以包括多個線程,並且線程共享整個進程的資源(寄存器、堆棧、上下文)。線程是進程內的一個執行單元,進程內至少有一個線程,線程才是真正的運行單位。它們共享進程的地址空間,而進程有自己獨立的地址空間。

(4)進程結束後它擁有的所有線程都將銷燬,而線程的結束不會影響同個進程中的其他線程的結束


本文的初衷為學習筆記的分享,部分圖文來源於網絡,如侵,聯刪。


分享到:


相關文章: