Python 協(xié)程與go協(xié)程的區(qū)別

進(jìn)程眉抬、線程和協(xié)程

進(jìn)程的定義:

進(jìn)程,是計(jì)算機(jī)中已運(yùn)行程序的實(shí)體瞒爬。程序本身只是指令弓柱、數(shù)據(jù)及其組織形式的描述,進(jìn)程才是程序的真正運(yùn)行實(shí)例侧但。

線程的定義:

操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位矢空。它被包含在進(jìn)程之中,是進(jìn)程中的實(shí)際運(yùn)作單位禀横。

進(jìn)程和線程的關(guān)系:

一條線程指的是進(jìn)程中一個(gè)單一順序的控制流屁药,一個(gè)進(jìn)程中可以并發(fā)多個(gè)線程,每條線程并行執(zhí)行不同的任務(wù)柏锄。

CPU的最小調(diào)度單元是線程不是進(jìn)程酿箭,所以單進(jìn)程多線程也可以利用多核CPU.

協(xié)程的定義:

協(xié)程通過在線程中實(shí)現(xiàn)調(diào)度,避免了陷入內(nèi)核級(jí)別的上下文切換造成的性能損失趾娃,進(jìn)而突破了線程在IO上的性能瓶頸缭嫡。

協(xié)程和線程的關(guān)系

協(xié)程是在語言層面實(shí)現(xiàn)對(duì)線程的調(diào)度,避免了內(nèi)核級(jí)別的上下文消耗抬闷。

python協(xié)程與調(diào)度

Python的協(xié)程源于yield指令妇蛀。yield有兩個(gè)功能:

yield item用于產(chǎn)出一個(gè)值,反饋給next()的調(diào)用方笤成。

作出讓步评架,暫停執(zhí)行生成器,讓調(diào)用方繼續(xù)工作炕泳,直到需要使用另一個(gè)值時(shí)再調(diào)用next()虫埂。


協(xié)程是對(duì)線程的調(diào)度课蔬,yield類似惰性求值方式可以視為一種流程控制工具靠胜,

實(shí)現(xiàn)協(xié)作式多任務(wù),在Python3.5正式引入了 async/await表達(dá)式,使得協(xié)程正式在語言層面得到支持和優(yōu)化栈暇,大大簡化之前的yield寫法。

線程是內(nèi)核進(jìn)行搶占式的調(diào)度的,這樣就確保了每個(gè)線程都有執(zhí)行的機(jī)會(huì)。

而 coroutine 運(yùn)行在同一個(gè)線程中塘砸,由語言的運(yùn)行時(shí)中的 EventLoop(事件循環(huán))來進(jìn)行調(diào)度节仿。

和大多數(shù)語言一樣晤锥,在 Python 中,協(xié)程的調(diào)度是非搶占式的廊宪,也就是說一個(gè)協(xié)程必須主動(dòng)讓出執(zhí)行機(jī)會(huì)矾瘾,其他協(xié)程才有機(jī)會(huì)運(yùn)行。

讓出執(zhí)行的關(guān)鍵字就是 await箭启。也就是說一個(gè)協(xié)程如果阻塞了壕翩,持續(xù)不讓出 CPU,那么整個(gè)線程就卡住了傅寡,沒有任何并發(fā)放妈。

PS: 作為服務(wù)端,event loop最核心的就是IO多路復(fù)用技術(shù)荐操,所有來自客戶端的請(qǐng)求都由IO多路復(fù)用函數(shù)來處理;作為客戶端芜抒,event loop的核心在于利用Future對(duì)象延遲執(zhí)行,并使用send函數(shù)激發(fā)協(xié)程,掛起,等待服務(wù)端處理完成返回后再調(diào)用CallBack函數(shù)繼續(xù)下面的流程

Go的協(xié)程

Go天生在語言層面支持托启,和Python類似都是采用了關(guān)鍵字宅倒,而Go語言使用了go這個(gè)關(guān)鍵字,可能是想表明協(xié)程是Go語言中最重要的特性屯耸。

go協(xié)程之間的通信拐迁,Go采用了channel關(guān)鍵字。

Go實(shí)現(xiàn)了兩種并發(fā)形式:

多線程共享內(nèi)存疗绣。如Java或者C++等在多線程中共享數(shù)據(jù)(例如數(shù)組线召、Map、或者某個(gè)結(jié)構(gòu)體或?qū)ο螅┑臅r(shí)候多矮,通過鎖來訪問.

Go語言特有的灶搜,也是Go語言推薦的:CSP(communicating sequential processes)并發(fā)模型。

Go的CSP并發(fā)模型實(shí)現(xiàn):M, P, G : [https://www.cnblogs.com/sunsk...]


通過在函數(shù)調(diào)用前使用關(guān)鍵字 go工窍,我們即可讓該函數(shù)以 goroutine 方式執(zhí)行割卖。goroutine 是一種 比線程更加輕盈、更省資源的協(xié)程患雏。

Go 語言通過系統(tǒng)的線程來多路派遣這些函數(shù)的執(zhí)行鹏溯,使得 每個(gè)用 go 關(guān)鍵字執(zhí)行的函數(shù)可以運(yùn)行成為一個(gè)單位協(xié)程。

當(dāng)一個(gè)協(xié)程阻塞的時(shí)候淹仑,調(diào)度器就會(huì)自 動(dòng)把其他協(xié)程安排到另外的線程中去執(zhí)行丙挽,從而實(shí)現(xiàn)了程序無等待并行化運(yùn)行肺孵。

而且調(diào)度的開銷非常小,一顆 CPU 調(diào)度的規(guī)模不下于每秒百萬次颜阐,這使得我們能夠創(chuàng)建大量的 goroutine平窘,

從而可以很輕松地編寫高并發(fā)程序,達(dá)到我們想要的目的凳怨。 ---- 某書

協(xié)程的4種狀態(tài)

Pending

Running

Done

Cacelled

和系統(tǒng)線程之間的映射關(guān)系

go的協(xié)程本質(zhì)上還是系統(tǒng)的線程調(diào)用瑰艘,而Python中的協(xié)程是eventloop模型實(shí)現(xiàn),所以雖然都叫協(xié)程肤舞,但并不是一個(gè)東西.

Python 中的協(xié)程是嚴(yán)格的 1:N 關(guān)系紫新,也就是一個(gè)線程對(duì)應(yīng)了多個(gè)協(xié)程。雖然可以實(shí)現(xiàn)異步I/O李剖,但是不能有效利用多核(GIL)芒率。

而 Go 中是 M:N 的關(guān)系,也就是 N 個(gè)協(xié)程會(huì)映射分配到 M 個(gè)線程上篙顺,這樣帶來了兩點(diǎn)好處:

多個(gè)線程能分配到不同核心上,CPU 密集的應(yīng)用使用 goroutine 也會(huì)獲得加速.

即使有少量阻塞的操作偶芍,也只會(huì)阻塞某個(gè) worker 線程,而不會(huì)把整個(gè)程序阻塞德玫。

PS: Go中很少提及線程或進(jìn)程,也就是因?yàn)樯厦娴脑?

兩種協(xié)程對(duì)比:

async是非搶占式的,一旦開始采用 async 函數(shù)匪蟀,那么你整個(gè)程序都必須是 async 的,不然總會(huì)有阻塞的地方(一遇阻塞對(duì)于沒有實(shí)現(xiàn)異步特性的庫就無法主動(dòng)讓調(diào)度器調(diào)度其他協(xié)程了)化焕,也就是說 async 具有傳染性萄窜。

Python 整個(gè)異步編程生態(tài)的問題,之前標(biāo)準(zhǔn)庫和各種第三方庫的阻塞性函數(shù)都不能用了撒桨,如:requests,redis.py,open 函數(shù)等查刻。所以 Python3.5后加入?yún)f(xié)程的最大問題不是不好用,而是生態(tài)環(huán)境不好,歷史包袱再次上演,動(dòng)態(tài)語言基礎(chǔ)上再加上多核之間的任務(wù)調(diào)度,應(yīng)該是很難的技術(shù)吧,真心希望python4.0能優(yōu)化或者放棄GIL鎖,使用多核提升性能凤类。

goroutine 是 go 與生俱來的特性穗泵,所以幾乎所有庫都是可以直接用的,避免了 Python 中需要把所有庫重寫一遍的問題谜疤。

goroutine 中不需要顯式使用 await 交出控制權(quán)佃延,但是 Go 也不會(huì)嚴(yán)格按照時(shí)間片去調(diào)度 goroutine,而是會(huì)在可能阻塞的地方插入調(diào)度夷磕。goroutine 的調(diào)度可以看做是半搶占式的履肃。

PS: python異步庫列表 [https://github.com/timofurrer...]

Do not communicate by sharing memory; instead, share memory by communicating.(不要以共享內(nèi)存的方式來通信,相反坐桩,要通過通信來共享內(nèi)存) -- CSP并發(fā)模型

擴(kuò)展與總結(jié)

erlang和golang都是采用了CSP(Communicating Sequential Processes)模式(Python中的協(xié)程是eventloop模型)

但是erlang是基于進(jìn)程的消息通信尺棋,go是基于goroutine和channel的通信。

Python和Go都引入了消息調(diào)度系統(tǒng)模型绵跷,來避免鎖的影響和進(jìn)程/線程開銷大的問題膘螟。

協(xié)程從本質(zhì)上來說是一種用戶態(tài)的線程成福,不需要系統(tǒng)來執(zhí)行搶占式調(diào)度,而是在語言層面實(shí)現(xiàn)線程的調(diào)度荆残。

因?yàn)閰f(xié)程不再使用共享內(nèi)存/數(shù)據(jù)奴艾,而是使用通信來共享內(nèi)存/鎖,因?yàn)樵谝粋€(gè)超級(jí)大系統(tǒng)里具有無數(shù)的鎖内斯,

共享變量等等會(huì)使得整個(gè)系統(tǒng)變得無比的臃腫蕴潦,而通過消息機(jī)制來交流,可以使得每個(gè)并發(fā)的單元都成為一個(gè)獨(dú)立的個(gè)體嘿期,

擁有自己的變量品擎,單元之間變量并不共享埋合,對(duì)于單元的輸入輸出只有消息备徐。

開發(fā)者只需要關(guān)心在一個(gè)并發(fā)單元的輸入與輸出的影響,而不需要再考慮類似于修改共享內(nèi)存/數(shù)據(jù)對(duì)其它程序的影響甚颂。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蜜猾,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子振诬,更是在濱河造成了極大的恐慌蹭睡,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赶么,死亡現(xiàn)場(chǎng)離奇詭異肩豁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)辫呻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門清钥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人放闺,你說我怎么就攤上這事祟昭。” “怎么了怖侦?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵篡悟,是天一觀的道長。 經(jīng)常有香客問我匾寝,道長搬葬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任艳悔,我火速辦了婚禮急凰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘很钓。我一直安慰自己香府,他們只是感情好董栽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著企孩,像睡著了一般锭碳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上勿璃,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天擒抛,我揣著相機(jī)與錄音,去河邊找鬼补疑。 笑死歧沪,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的莲组。 我是一名探鬼主播诊胞,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼锹杈!你這毒婦竟也來了撵孤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤竭望,失蹤者是張志新(化名)和其女友劉穎邪码,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咬清,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡闭专,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了旧烧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片影钉。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖粪滤,靈堂內(nèi)的尸體忽然破棺而出斧拍,到底是詐尸還是另有隱情,我是刑警寧澤杖小,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布肆汹,位于F島的核電站,受9級(jí)特大地震影響予权,放射性物質(zhì)發(fā)生泄漏昂勉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一扫腺、第九天 我趴在偏房一處隱蔽的房頂上張望岗照。 院中可真熱鬧,春花似錦、人聲如沸攒至。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迫吐。三九已至库菲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間志膀,已是汗流浹背熙宇。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留溉浙,地道東北人烫止。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像戳稽,于是被迫代替她去往敵國和親馆蠕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 最近經(jīng)常有同學(xué)在小猿圈網(wǎng)站留言說:小猿圈網(wǎng)站上邊的課程太多了广鳍,而且全部免費(fèi)荆几,自己就忍不住都想學(xué)習(xí)吓妆,尤其是學(xué)習(xí)了py...
    小猿圈IT教育閱讀 353評(píng)論 0 0
  • 一. 操作系統(tǒng)概念 操作系統(tǒng)位于底層硬件與應(yīng)用軟件之間的一層.工作方式: 向下管理硬件,向上提供接口.操作系統(tǒng)進(jìn)行...
    月亮是我踢彎得閱讀 5,965評(píng)論 3 28
  • 輕量級(jí)線程:協(xié)程 在常用的并發(fā)模型中行拢,多進(jìn)程祖秒、多線程、分布式是最普遍的舟奠,不過近些年來逐漸有一些語言以first-c...
    Tenderness4閱讀 6,364評(píng)論 2 10
  • 1竭缝、并發(fā)與并行 并行(parallel):指在同一時(shí)刻,有多條指令在多個(gè)處理器上同時(shí)執(zhí)行沼瘫。并發(fā)(concurren...
    lesline閱讀 9,560評(píng)論 0 2
  • 這幾天看了看操作系統(tǒng)抬纸,順便研究了一下Python的協(xié)程,下面就是做的一點(diǎn)筆記 協(xié)程是什么? 協(xié)程耿戚,英文Corout...
    Miracle778閱讀 2,850評(píng)論 0 4