一個故事講完程式、執行緒和協程(作業系統基礎知識)
轉自:碼農翻身(微訊號:coderising)
很久以前,有兩個程式,暫且稱他們旺財和小強吧。
旺財和小強這兩個程式都很長,每個都有十幾萬行。 他們兩個的人生價值就是到CPU上去執行,把執行結果告訴人類。
CPU是稀缺資源,只有一個,他們倆必須排著隊,輪流使用。
旺財從頭到尾執行完了,讓出CPU, 讓小強從頭兒去執行。
人類把這種處理方式叫做 批處理。
程式
長久以來,兩人相安無事。 後來CPU的速度越來越快, 遠遠超過了記憶體,硬碟的速度。
人類想到,這批處理系統的效率有點低啊,你看當小強需要從硬碟上讀取資料的時候,CPU也一直在等待,這是多大的浪費啊!這時候完全可以讓旺財來執行一下嘛!
當然得儲存好小強的 執行現場:具體執行到那一行程式指令了, 函式呼叫到什麼層次了,每個函式呼叫都有什麼樣的引數,CPU暫存器中的值… 等等一系列東西。
如果不把小強的執行現場給儲存下來,等到小強的資料從銀盤讀完了,就沒法回到中斷處來繼續執行了。
這個執行現場,再加上小強的程式碼,就是一個執行中的程式,被稱為 程式 。
旺財和小強在執行的時候,也被改造成了程式。
人類還規定:程式不能長時間佔據CPU, 只能在CPU上執行一小會兒,然後馬上切換到別的程式去執行。
旺財和小強不以為意:不就是執行一會兒,歇一會兒,然後繼續執行嘛!
但是他們不知道的是,由於CPU執行速度超快,旺財和小強雖然在不斷地切換執行,在人類那緩慢的世界裡看來,旺財和小強好像是同時在執行一樣。 這就是 併發。
(在人類看來,小強和旺財似乎是在同時執行)
多年以後,他們倆才真正地實現了 並行: 在一個豪華電腦中,每人都被分配了一個CPU , 真正地同時執行, 這是後話了。
執行緒
這時候旺財在 已經有了介面,還能訪問網路,每當它聯網的時候(這也是個非常非常耗時的操作),就得把CPU讓給小強。
即使旺財再次被排程執行,由於網路資料還沒有返回,他必須等待,什麼事情都做不了,在人類看來,介面根本無法操作,旺財不響應了! 氣得人類經常把旺財kill掉。
旺財心裡苦,他很納悶小強怎麼就沒有問題,小強不是要讀寫硬碟嗎? 那也是很慢的操作啊。
小強說:“你傻啊,內部只有一個執行的流程,一遇到耗時的操作就得等待,你看看我,內部搞了兩個執行流程( 執行緒),一個用來讀寫硬碟(T1),另外一個處理介面(T2)。我和作業系統商量好了,如果T1在讀寫硬碟, 就可以排程我的T2來執行,這樣介面至少還可以操作。 ”
旺財覺得很有意思,也採用了類似辦法。
於是,一個程式中至少有一個執行的流程(主執行緒),也可以開啟新的執行流程(執行緒)。
執行緒變成了最小的排程單位。
協程
這一天,旺財被一個叫做生產者和消費者的問題折騰地死去活來,兩個執行緒,一個執行緒向佇列中放資料,另外一個從佇列中取資料,處理起兩個執行緒的協作就顯得很麻煩,不但需要加鎖,還得做好執行緒的通知和等待。
正在感慨多執行緒程式設計之難的時候, 旺財震驚地發現,小強用了一個極為簡單的辦法把生產者,消費者問題給解決了。
這個方法的程式碼如下:
# 生產者 def producer(c): #其他程式碼 while True: value = ...生成資料... c.send(value) # 消費者 def consumer(): #其他程式碼 while True: value = yield print(value) c = consumer() producer(c)
“這…這怎麼執行啊,那個yield是怎麼回事?” 旺財表示不解。
“簡單啊,你看那個生產者,是不是向消費者傳送了資料? ” 小強說。
“對啊,然後呢,生產者傳送了資料以後,會馬上進行下一輪迴圈嗎?”
“這就是關鍵所在了,”小強說,“ 它們是這麼執行的:”
1.生產者傳送資料,暫停執行,不進行下一輪迴圈
2.消費者其實一直在value = yield 那裡等待,直到資料到來,現在資料來了,取出處理(value就是生產者傳送過來的資料)。
3.消費者在迴圈中再次yield, 暫停執行。
4.生產者繼續下一輪的迴圈,生成新的訊息,傳送給消費者。
旺財覺得很吃驚,小強竟然 可以讓一個正在執行的程式暫停,他不由得問道:“你這個暫停是真的停止了了,還是說只是像Java的yield那樣,讓出CPU進入了就緒狀態? 等待下次排程執行?”
“是真的暫停了,程式就停在那裡,等待執行控制權從對方那裡轉移過來。”
“這不是作業系統乾的事情嗎? ” 旺財更加吃驚了。
“正是這樣,” 小強得意地說:“我打算把類似生產者,消費者這樣的程式碼稱為‘ 協程’, 這個協程有個重要的特點,就是完全被我所排程和掌控, 不用作業系統介入。”
“這個協程和執行緒似乎很像啊。每次協程停止執行的時候,也得儲存現場,要不然沒法恢復執行。” 旺財說。
“是啊,只是他們 比執行緒更加輕量級,作業系統核心不用參與,相當於使用者態執行緒了, 協程的開銷極小,可以輕鬆地建立大量的協程來做事情。 對了,也許你注意到了,我這兩個協程是’ 合作式’的,它們兩個同一時刻只能有一個在執行。 實際上,我在底層可以用一個執行緒去執行這兩個協程。 ”
旺財表示同意:“不錯,既然兩個程式可以’合作’,那就不用加鎖了,也不用在程式碼裡寫什麼wait和notify了,在程式層面,可以用同步的方式實現非同步的功能了! 程式碼很清晰,我也搞個協程來玩玩吧!”
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69947338/viewspace-2656370/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 程式,核心執行緒,使用者執行緒,協程,纖程......作業系統世界觀執行緒作業系統
- 作業系統知識回顧(2)--程式與執行緒作業系統執行緒
- LINUX作業系統知識:程式與執行緒詳解Linux作業系統執行緒
- Android 基礎知識——執行緒Android執行緒
- 多執行緒基礎知識執行緒
- [作業系統]程式基礎知識記錄(上)作業系統
- 【作業系統】程式與執行緒作業系統執行緒
- 作業系統——深入理解程式和執行緒作業系統執行緒
- 作業系統-執行緒和程式的區別作業系統執行緒
- 作業系統_程式和執行緒的區別作業系統執行緒
- 作業系統基礎第一講作業系統
- 前置知識—程式和執行緒執行緒
- 作業系統-執行緒作業系統執行緒
- 程式、執行緒和協程的概念執行緒
- 多執行緒基礎知識點梳理執行緒
- 協程庫基礎知識
- Python——程式、執行緒、協程、多程式、多執行緒(個人向)Python執行緒
- java基礎:執行緒與程式;執行緒的分工,協作,互斥;volatile關鍵字Java執行緒
- Java多執行緒程式設計基礎知識彙總Java執行緒程式設計
- 【作業系統】1.程序和執行緒作業系統執行緒
- 什麼是程式、執行緒和協程?執行緒
- 作業系統:多執行緒作業系統執行緒
- 協程、執行緒與程式執行緒
- java多執行緒基礎知識速通Java執行緒
- Java 執行緒和作業系統的執行緒有啥區別?Java執行緒作業系統
- Thread執行緒知識點講解thread執行緒
- 程式執行緒篇——程式執行緒基礎執行緒
- 作業系統基礎第四講作業系統
- 作業系統基礎第三講作業系統
- 作業系統基礎第二講作業系統
- 作業系統複習(程式、執行緒、死鎖)作業系統執行緒
- jvm、gc、作業系統等基礎知識總結JVMGC作業系統
- Android小知識-Java多執行緒的基礎知識瞭解下AndroidJava執行緒
- 多執行緒基礎必要知識點!看了學習多執行緒事半功倍執行緒
- 程式執行緒協程關係執行緒
- 理解作業系統之程式和執行緒作業系統執行緒
- 【作業系統】程式的描述與控制[執行緒](4)作業系統執行緒
- Java基礎知識回顧之五 ----- 多執行緒Java執行緒