1. 程式人生 > >程序、執行緒與協程

程序、執行緒與協程

程序

程序的出現是為了更好的利用CPU資源使到併發成為可能。 假設有兩個任務A和B,當A遇到IO操作,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上的效能瓶頸。 當涉及到大規模的併發連線時,例如10K連線。以執行緒作為處理單元,系統排程的開銷還是過大。當連線數很多 —> 需要大量的執行緒來幹活 —> 可能大部分的執行緒處於ready狀態 —> 系統會不斷地進行上下文切換。既然效能瓶頸在上下文切換,那解決思路也就有了,線上程中自己實現排程,不陷入核心級別的上下文切換。說明一下,在歷史上協程比執行緒要出現得早,在1963年首次提出, 但沒有流行開來。為什麼沒有流行,沒有找到信服的資料,先挖個坑,以後那天瞭解後,再補上。

小結

程序,執行緒,協程不斷突破,更高效的處理阻塞,不斷地提高CPU的利用率。但是並不是說,執行緒就一定比程序快,而協程就一定不執行緒要快。具體還是要看應用場景。可以簡單粗暴的把應用分為IO密集型應用以及CPU密集型應用。

多核CPU,CPU密集型應用
此時多執行緒的效率是最高的,多執行緒可以使到全部CPU核心滿載,又避免了協程間切換造成效能損失。當CPU密集型任務時,CPU一直在利用著,切換反而會造成效能損失,即便協程上下文切換消耗最小,但也還是有消耗的。

多核CPU,IO密集型應用
此時採用多執行緒多協程效率最高,多執行緒可以使到全部CPU核心滿載,而一個執行緒多協程,則更好的提高了CPU的利用率。

單核CPU,CPU密集型應用
單程序效率是最高,此時單個程序已經使到CPU滿載了。

單核CPU,IO密集型應用
多協程,效率最高。例如,看了上面應該也是知道的了

作者:Ljian1992
連結:http://www.jianshu.com/p/f11724034d50
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。