欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入淺析python 協(xié)程與go協(xié)程的區(qū)別

 更新時間:2019年05月09日 15:03:59   作者:lgj_bky  
這篇文章主要介紹了python 協(xié)程與go協(xié)程的區(qū)別 ,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下

進程、線程和協(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()。

import asyncio
import datetime
async def display_date():
 loop = asyncio.get_running_loop()
 end_time = loop.time() + 5.0
 while True:
  print(datetime.datetime.now())
  if (loop.time() + 1.0) >= end_time:
   break
  await asyncio.sleep(1)
asyncio.run(display_date())

協(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é)程是天生在語言層面支持,和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 :

package main
import (
 "fmt"
)
//Go 協(xié)程(goroutines)和協(xié)程(coroutines)
//Go 協(xié)程意味著并行(或者可以以并行的方式部署),協(xié)程一般來說不是這樣的
//Go 協(xié)程通過通道來通信;協(xié)程通過讓出和恢復(fù)操作來通信
// 進程退出時不會等待并發(fā)任務(wù)結(jié)束,可用通道(channel)阻塞,然后發(fā)出退出信號
func main() {
 jobs := make(chan int)
 done := make(chan bool) // 結(jié)束標(biāo)志
 go func() {
  for {
   j, more := <-jobs // 利用more這個值來判斷通道是否關(guān)閉,如果關(guān)閉了,那么more的值為false,并且通知給通道done
   fmt.Println("----->:", j, more)
   if more {
    fmt.Println("received job", j)
   } else {
    fmt.Println("end received jobs")
    done <- true
    return
   }
  }
 }()
 go func() {
  for j := 1; j <= 3; j++ {
   jobs <- j
   fmt.Println("sent job", j)
  }
  close(jobs) // 寫完最后的數(shù)據(jù),緊接著就close掉
  fmt.Println("close(jobs)")
 }()
 fmt.Println("sent all jobs")
 <-done // 讓main等待全部協(xié)程完成工作
}

通過在函數(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)的問題,之前標(biāo)準(zhǔn)庫和各種第三方庫的阻塞性函數(shù)都不能用了,requests 不能用了,redis.py 不能用了,甚至 open 函數(shù)都不能用了。所以 Python 協(xié)程的最大問題不是不好用,而是生態(tài)環(huán)境不好。
•goroutine 是 go 與生俱來的特性,所以幾乎所有庫都是可以直接用的,避免了 Python 中需要把所有庫重寫一遍的問題。
•Goroutine 中不需要顯式使用 await 交出控制權(quán),但是 Go 也不會嚴格按照時間片去調(diào)度 goroutine,而是會在可能阻塞的地方插入調(diào)度。Goroutine 的調(diào)度可以看做是半搶占式的。

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

--------------------------------------------------------------------------------

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ù)對其它程序的影響。

相關(guān)文章

  • 出現(xiàn)module 'queue' has no attribute 'Queue'問題的解決

    出現(xiàn)module 'queue' has no attrib

    這篇文章主要介紹了出現(xiàn)module 'queue' has no attribute 'Queue'問題的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • python基礎(chǔ)之局部變量和全局變量

    python基礎(chǔ)之局部變量和全局變量

    這篇文章主要介紹了python局部變量和全局變量,實例分析了Python中返回一個返回值與多個返回值的方法,需要的朋友可以參考下
    2021-10-10
  • Django自動注冊tasks及使用方式

    Django自動注冊tasks及使用方式

    這篇文章主要為大家介紹了Django自動注冊tasks及使用方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • 500行代碼使用python寫個微信小游戲飛機大戰(zhàn)游戲

    500行代碼使用python寫個微信小游戲飛機大戰(zhàn)游戲

    這篇文章主要介紹了500行代碼使用python寫個微信小游戲飛機大戰(zhàn)游戲,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-10-10
  • Python實現(xiàn)雞群算法的示例代碼

    Python實現(xiàn)雞群算法的示例代碼

    雞群算法,縮寫為CSO(Chicken?Swarm?Optimization),盡管具備所謂仿生學(xué)的背景,但實質(zhì)上是粒子群算法的一個變體。本文將利用Python語言實現(xiàn)這一算法,感興趣的可以了解一下
    2022-11-11
  • Python游戲開發(fā)實例之graphics實現(xiàn)AI五子棋

    Python游戲開發(fā)實例之graphics實現(xiàn)AI五子棋

    五子棋是經(jīng)典的棋牌類游戲,很多人都玩過,那么如何用Python實現(xiàn)五子棋呢,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • 利用tkinter實現(xiàn)下拉框聯(lián)動

    利用tkinter實現(xiàn)下拉框聯(lián)動

    這篇文章主要介紹了利用tkinter實現(xiàn)下拉框聯(lián)動問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • postman模擬訪問具有Session的post請求方法

    postman模擬訪問具有Session的post請求方法

    今天小編就為大家分享一篇postman模擬訪問具有Session的post請求方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • Python中的pandas模塊詳解

    Python中的pandas模塊詳解

    在Python中使用pandas模塊,需要先安裝pandas庫,pandas模塊是Python編程語言中用于數(shù)據(jù)處理和分析的強大模塊,它提供了許多用于數(shù)據(jù)操作和清洗的函數(shù),使得數(shù)據(jù)處理和分析變得更為簡單和直觀,本文給大家介紹Python pandas模塊,感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • 將Python腳本打包成MACOSAPP程序過程

    將Python腳本打包成MACOSAPP程序過程

    我們編寫python程序時,有時候需要想將python腳本轉(zhuǎn)成可執(zhí)行的程序或者app,可以直接通過雙擊執(zhí)行即可,像Windows上可以將其通過工具轉(zhuǎn)換成exe程序,那么在MACOS下我們可以將其打包成MACOS APP程序
    2021-09-09

最新評論