協程VS進程VS線程

什麼是進程和線程?

進程是應用程序的啓動實例,進程擁有代碼和打開的文件資源、數據資源、獨立的內存空間。

線程從屬於進程,是程序的實際執行者,一個進程至少包含一個主線程,也可以有更多的子線程,線程擁有自己的棧空間。

操作系統中的進程和線程

對操作系統而言,線程是最小的執行單元,進程是最小的資源管理單元。無論是進程還是線程,都是由操作系統所管理的。

線程的狀態

線程具有五種狀態:初始化、可運行、運行中、阻塞、銷燬

線程狀態的轉化關係

線程之間是如何進行協作的呢?

最經典的例子是生產者/消費者模式,即若干個生產者線程向隊列中系欸如數據,若干個消費者線程從隊列中消費數據。

生產者/消費者模式

生產者/消費者模式的性能問題是什麼?

  • 涉及到同步鎖
  • 涉及到線程阻塞狀態和可運行狀態之間的切換
  • 設置到線程上下文的切換

什麼是協程呢?

協程(Coroutines)是一種比線程更加輕量級的存在,正如一個進程可以擁有多個線程一樣,一個線程可以擁有多個協程。

操作系統中的協程

協程不是被操作系統內核所管理的,而是完全由程序所控制,也就是在用戶態執行。這樣帶來的好處是性能大幅度的提升,因爲不會像線程切換那樣消耗資源。

協程不是進程也不是線程,而是一個特殊的函數,這個函數可以在某個地方掛起,並且可以重新在掛起處外繼續運行。所以說,協程與進程、線程相比並不是一個維度的概念。

一個進程可以包含多個線程,一個線程也可以包含多個協程。簡單來說,一個線程內可以由多個這樣的特殊函數在運行,但是有一點必須明確的是,一個線程的多個協程的運行是串行的。如果是多核CPU,多個進程或一個進程內的多個線程是可以並行運行的,但是一個線程內協程卻絕對是串行的,無論CPU有多少個核。畢竟協程雖然是一個特殊的函數,但仍然是一個函數。一個線程內可以運行多個函數,但這些函數都是串行運行的。當一個協程運行時,其它協程必須掛起。

進程、線程、協程的對比

  • 協程既不是進程也不是線程,協程僅僅是一個特殊的函數,協程它進程和進程不是一個維度的。
  • 一個進程可以包含多個線程,一個線程可以包含多個協程。
  • 一個線程內的多個協程雖然可以切換,但是多個協程是串行執行的,只能在一個線程內運行,沒法利用CPU多核能力。
  • 協程與進程一樣,切換是存在上下文切換問題的。

上下文切換

  • 進程的切換者是操作系統,切換時機是根據操作系統自己的切換策略,用戶是無感知的。進程的切換內容包括頁全局目錄、內核棧、硬件上下文,切換內容保存在內存中。進程切換過程是由“用戶態到內核態到用戶態”的方式,切換效率低。

  • 線程的切換者是操作系統,切換時機是根據操作系統自己的切換策略,用戶無感知。線程的切換內容包括內核棧和硬件上下文。線程切換內容保存在內核棧中。線程切換過程是由“用戶態到內核態到用戶態”, 切換效率中等。

  • 協程的切換者是用戶(編程者或應用程序),切換時機是用戶自己的程序所決定的。協程的切換內容是硬件上下文,切換內存保存在用戶自己的變量(用戶棧或堆)中。協程的切換過程只有用戶態,即沒有陷入內核態,因此切換效率高。

協程的開銷爲什麼遠遠小於線程的開銷呢?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章