淺談程序、執行緒和協程三者之間的區別和聯絡
阿新 • • 發佈:2018-12-08
一、程序、執行緒、協程
1,程序
經典定義:一個執行中程式的例項。系統中的每個程式都執行在某個程序的上下文中。(-摘自 CSAPP)
程序是系統資源分配的最小單位
2,執行緒(thread)
執行緒就是執行在程序上下文中的邏輯流。
執行緒是作業系統能夠進行運算排程的最小單位。
3,協程
相對子例程而言,協程更為一般和靈活,但在實踐中使用沒有子例程那樣廣泛。
根據維基百科對子例程的描述:是一個大型程式中的某部分程式碼,由一個或多個語句塊組成。它負責完成某項特定任務,而且相較於其他程式碼,具備相對的獨立性。我可以將子例程理解為一個函式。
4,區別和聯絡
首先,程序提供給應用程式的關鍵抽象為:
- 一個獨立的邏輯控制流:它提供一個假象,好像我們的程式獨佔地使用處理器。
- 一個私有的地址空間,它提供一個假象,好像我們的程式獨佔地使用記憶體系統。
從以上描述我可以看出,一個程序是一個獨立進行的任務,它佔用的系統資源有:地址空間,全域性變數,檔案描述符,硬體資源等。
程序出現的目的,是為了更好的利用CPU資源。例如:
假設有兩個任務A和B,當A遇到IO操作,CPU默默的等待任務A讀取完操作再去執行任務B,這樣無疑是對CPU資源的極大的浪費。若在任務A讀取資料時,讓任務B執行,當任務A讀取完資料後,再切換
因此,通過程序來分配系統資源,標識任務。
如何分配CPU去執行程序稱之為排程,程序狀態的記錄,恢復,上下文切換(簡稱切換)。
其次,若上面提及的任務A是一個文字程式,需要接受鍵盤輸入,將內容顯示在螢幕上,還需要儲存資訊到硬碟中。
若只有一個程序,會造成同一時間只能幹一樣事的尷尬(當儲存時,就不能通過鍵盤輸入內容)。若有多個程序,每個程序負責一個任務,程序A負責接收鍵盤輸入的任務,程序B負責將內容顯示在螢幕上的任務,程序C負責儲存內容到硬碟中的任務。這裡程序A,B,C間的協作涉及到了程序通訊問題,而且有共同都需要擁有的東西-------文字內容,不停的切換造成效能上的損失。若有一種機制,可以使任務A,B,C共享資源,這樣上下文切換所需要儲存和恢復的內容就少了,同時又可以減少通訊所帶來的效能損耗,那就好了。這時執行緒出現了。 因此,執行緒共享程序的大部分資源,並參與CPU的排程。二、小結
之前做遊戲伺服器時就對這塊概念不是很清晰,現在做流媒體服務時又碰到了這樣的困惑,因此專門看書思考整理了相關的知識點,網上也參考了許多例子。如果有錯誤還望及時指正。 在此引用一位從事伺服器開發的前輩說的話:核心只有一個, 執行緒是作業系統排程,協程是使用者態排程。
協程不必須是語言整合,例如C語言可以用setjmp/longjmp實現,也可以自己通過改變esp指標換棧實現協程。 協程本身跟高吞吐沒任何關係,基於io多路複用+回撥就可以實現高併發和高吞吐。 引入協程是為了將回調邏輯變成線性同步邏輯。
參考資料
程序、執行緒、輕量級程序、協程與 go 的 goroutine【轉載+整理】