日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

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

系統(tǒng) 1675 0

進程、線程和協(xié)程

進程的定義:

進程,是計算機中已運行程序的實體。程序本身只是指令、數(shù)據(jù)及其組織形式的描述,進程才是程序的真正運行實例。

線程的定義:

操作系統(tǒng)能夠進行運算調(diào)度的最小單位。它被包含在進程之中,是進程中的實際運作單位。

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

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

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

協(xié)程的定義:

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

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

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

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

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

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

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


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

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

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

而 coroutine 運行在同一個線程中,由語言的運行時中的 EventLoop(事件循環(huán))來進行調(diào)度。

和大多數(shù)語言一樣,在 Python 中,協(xié)程的調(diào)度是非搶占式的,也就是說一個協(xié)程必須主動讓出執(zhí)行機會,其他協(xié)程才有機會運行。

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

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

Go的協(xié)程

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

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

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

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

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

Go的CSP并發(fā)模型實現(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í)行,使得 每個用 go 關(guān)鍵字執(zhí)行的函數(shù)可以運行成為一個單位協(xié)程。

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

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

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

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

Pending

Running

Done

Cacelled

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

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

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

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

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

即使有少量阻塞的操作,也只會阻塞某個 worker 線程,而不會把整個程序阻塞。

PS: Go中很少提及線程或進程,也就是因為上面的原因.

兩種協(xié)程對比:

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

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

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

goroutine 中不需要顯式使用 await 交出控制權(quán),但是 Go 也不會嚴格按照時間片去調(diào)度 goroutine,而是會在可能阻塞的地方插入調(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ā)模型

擴展與總結(jié)

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

但是erlang是基于進程的消息通信,go是基于goroutine和channel的通信。

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

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

因為協(xié)程不再使用共享內(nèi)存/數(shù)據(jù),而是使用通信來共享內(nèi)存/鎖,因為在一個超級大系統(tǒng)里具有無數(shù)的鎖,

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

擁有自己的變量,單元之間變量并不共享,對于單元的輸入輸出只有消息。

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


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 博乐市| 山东| 大竹县| 怀柔区| 金门县| 阆中市| 正宁县| 于田县| 石楼县| 杂多县| 留坝县| 油尖旺区| 桑植县| 五莲县| 黑山县| 宜兰市| 长汀县| 安泽县| 潞西市| 永新县| 宁陕县| 德兴市| 疏附县| 彭泽县| 嵩明县| 镇宁| 射阳县| 监利县| 库车县| 中西区| 石台县| 宜都市| 南汇区| 德兴市| 吉林省| 英超| 肥乡县| 扎囊县| 青川县| 阳高县| 屏东市|