最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python的協(xié)程操作幾種實(shí)現(xiàn)方式總結(jié)

 更新時(shí)間:2025年09月01日 10:39:46   作者:EvanSun__  
在Python中協(xié)程(Coroutine)是一種強(qiáng)大的并發(fā)編程工具,允許你以非阻塞方式處理I/O密集型任務(wù)、異步操作等場(chǎng)景,這篇文章主要介紹了Python的協(xié)程操作幾種實(shí)現(xiàn)方式,需要的朋友可以參考下

并發(fā)的本質(zhì): 切換+保存狀態(tài)

概念

協(xié)程是單線程下的并發(fā),又稱(chēng)微線程,纖程。英文名Coroutine。是python個(gè)中另外一種實(shí)現(xiàn)多任務(wù)的方式,只不過(guò)比線程更小占用更小執(zhí)行單元(理解為需要的資源)。為啥說(shuō)它是一個(gè)執(zhí)行單元,因?yàn)樗詭PU上下文。這樣只要在合適的時(shí)機(jī),我們可以把一個(gè)協(xié)程切換到另一個(gè)協(xié)程。只要這個(gè)過(guò)程中保存或恢復(fù) CPU上下文那么程序還是可以運(yùn)行的。

協(xié)程是一種用戶(hù)態(tài)的輕量級(jí)線程,即協(xié)程是由用戶(hù)程序自己控制調(diào)度的。

通俗理解

在一個(gè)線程中的某個(gè)函數(shù),可以在任何地方保存當(dāng)前函數(shù)的一些臨時(shí)變量等信息,然后切換到另外一個(gè)函數(shù)中執(zhí)行,注意不是通過(guò)調(diào)用函數(shù)的方式做到的,并且切換的次數(shù)以及什么時(shí)候再切換到原來(lái)的函數(shù)都由開(kāi)發(fā)者自己確定

協(xié)程和線程差異

在實(shí)現(xiàn)多任務(wù)時(shí), 線程切換從系統(tǒng)層面遠(yuǎn)不止保存和恢復(fù)CPU上下文這么簡(jiǎn)單。 操作系統(tǒng)為了程序運(yùn)行的高效性每個(gè)線程都有自己緩存Cache等等數(shù)據(jù),操作系統(tǒng)還會(huì)幫你做這些數(shù)據(jù)的恢復(fù)操作。 所以線程的切換非常耗性能。但是協(xié)程的切換只是單純的操作CPU的上下文,所以一秒鐘切換個(gè)上百萬(wàn)次系統(tǒng)都抗的住。

協(xié)程的優(yōu)勢(shì)

  1. 協(xié)程的切換開(kāi)銷(xiāo)更小,屬于程序級(jí)別的切換,操作系統(tǒng)完全感知不到,因而更加輕量級(jí)

  2. 單線程內(nèi)就可以實(shí)現(xiàn)并發(fā)的效果,最大限度地利用cpu

協(xié)程的缺點(diǎn)

  1. 協(xié)程的本質(zhì)是單線程下,無(wú)法利用多核,可以是一個(gè)程序開(kāi)啟多個(gè)進(jìn)程,每個(gè)進(jìn)程內(nèi)開(kāi)啟多個(gè)線程,每個(gè)線程內(nèi)開(kāi)啟協(xié)程
  2. 協(xié)程指的是單個(gè)線程,因而一旦協(xié)程出現(xiàn)阻塞,將會(huì)阻塞整個(gè)線程

協(xié)程的特點(diǎn)

  1. 必須在只有一個(gè)單線程里實(shí)現(xiàn)并發(fā)
  2. 修改共享數(shù)據(jù)不需加鎖
  3. 用戶(hù)程序里自己保存多個(gè)控制流的上下文棧
  4. 附加:一個(gè)協(xié)程遇到IO操作自動(dòng)切換到其它協(xié)程(如何實(shí)現(xiàn)檢測(cè)IO,yield、greenlet都無(wú)法實(shí)現(xiàn),就用到了 gevent模塊(select機(jī)制))

協(xié)程的本質(zhì)

協(xié)程的本質(zhì)就是在單線程下,由用戶(hù)自己控制一個(gè)任務(wù)遇到io阻塞了就切換另外一個(gè)任務(wù)去執(zhí)行,以此來(lái)提升效率。

實(shí)現(xiàn)方式

方式一 Greenlet 模塊

首先要安裝Greenlet模塊 pip install greenlet

import time
from greenlet import greenlet

def study(name):
    print(f"{name} 正在學(xué)習(xí)面向?qū)ο?..")
    time.sleep(2)
    g2.switch("qiaoba")		
    print(f"{name} 正在學(xué)習(xí)協(xié)程...")
    g2.switch("qiaoba")

def play(name):
    print(f"{name} 正在玩超級(jí)瑪麗...")
    time.sleep(2)
    g1.switch("lufei")
    print(f"{name} 正在玩CS...")

g1 = greenlet(study)	# xxx = greenlet(fun方法名)
g2 = greenlet(play)
g1.switch("lufei")		# 使用xxx.switch("參數(shù)") 手動(dòng)切換另一個(gè)方法

缺點(diǎn)是遇到IO阻塞不會(huì)自動(dòng)切換,需要人工切換,比較麻煩

方式二 Gevent模塊

python還有一個(gè)比greenlet更強(qiáng)大的并且能夠自動(dòng)切換任務(wù)的模塊 gevent

原理是當(dāng)一個(gè)greenlet遇到IO(指的是input output 輸入輸出,比如網(wǎng)絡(luò)、文件操作等)操作時(shí),比如訪問(wèn)網(wǎng)絡(luò),就自動(dòng)切換到其他的greenlet,等到IO操作完成,再在適當(dāng)?shù)臅r(shí)候切換回來(lái)繼續(xù)執(zhí)行。由于IO操作非常耗時(shí),經(jīng)常使程序處于等待狀態(tài),有了gevent為我們自動(dòng)切換協(xié)程,就保證總有g(shù)reenlet在運(yùn)行,而不是等待IO

首先要安裝Gevent模塊 pip3 install gevent

用法
g1 = gevent.spawn(fun方法名,args參數(shù)1,x=args參數(shù)2...)  # 創(chuàng)建一個(gè)協(xié)程對(duì)象g1,參數(shù)是傳給方法的位置實(shí)參或關(guān)鍵字實(shí)參
g1.join()  # 等待g1結(jié)束
gevent.joinall([g1,g2])  # 等待g1g2全部結(jié)束
g1.value   # 獲得g1的返回值

原來(lái)的gevent不能識(shí)別原程序中的耗時(shí)操作的代碼,必須要替換為gevent自帶的方法。

可以通過(guò) 打補(bǔ)丁 的方式將程序中用到的耗時(shí)操作的代碼,自動(dòng)替換為gevent中自己實(shí)現(xiàn)的模塊,這樣例如time.sleep()等耗時(shí)操作gevent便可以識(shí)別了

from gevent import monkey
monkey.patch_all()  # 自動(dòng)替換全部耗時(shí)操作的代碼

方式三(模擬) yield

import time

def consumer():
    while 1:
        x = yield 0
        print(x)
        
def producer():
    g = consumer()
    g.__next__()
    for i in range(100):
        g.send(i)
        print(i)
start = time.time()
producer()
print(time.time()-start)  # 0.0010056495666503906

start = time.time()
for i in range(100):
    print(i)
print(time.time()-start)  # 0.0010077953338623047

方法四 asyncio模塊(已過(guò)時(shí))

在Python3.4之前官方未提供協(xié)程的類(lèi)庫(kù),一般大家都是使用greenlet等其 他來(lái)實(shí)現(xiàn)。在Python3.4發(fā)布后官方正式支持協(xié)程,即:asyncio模塊。

import asyncio
@asyncio.coroutine
def func1():
    print(1)
    yield from asyncio.sleep(2)  # 遇到IO耗時(shí)操作,自動(dòng)化切換到tasks中的其他任務(wù)
print(2)
@asyncio.coroutine
def func2():
    print(3)
    yield from asyncio.sleep(2) # 遇到IO耗時(shí)操作,自動(dòng)化切換到tasks中的其他任務(wù)
    print(4)
tasks = [
    asyncio.ensure_future( func1() ),
    asyncio.ensure_future( func2() )
]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

方法五 async & awit 模塊

async & awit 關(guān)鍵字在Python3.5版本中正式引入,基于他編寫(xiě)的協(xié)程代碼 其實(shí)就是 上一示例 的加強(qiáng)版,讓代碼可以更加簡(jiǎn)便。Python3.8之后@asyncio.coroutine 裝飾器就會(huì)被移除,推薦使用 async & awit 關(guān)鍵字實(shí)現(xiàn)協(xié)程代碼。

import asyncio
async def func1():
   print(1)
   await asyncio.sleep(2)
   print(2)
async def func2():
   print(3)
   await asyncio.sleep(2)
   print(4)
tasks = [
   asyncio.ensure_future(func1()),
   asyncio.ensure_future(func2())
]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

進(jìn)程、線程和協(xié)程的簡(jiǎn)單總結(jié)

  • 進(jìn)程是資源分配的單位
  • 線程是操作系統(tǒng)調(diào)度的單位
  • 進(jìn)程切換需要的資源很最大,效率很低
  • 線程切換需要的資源一般,效率一般(當(dāng)然了在不考慮GIL的情況下)
  • 協(xié)程切換任務(wù)資源很小,效率高
  • 多進(jìn)程、多線程根據(jù)cpu核數(shù)不一樣可能是并行的,但是協(xié)程是在一個(gè)線程中 所以是并發(fā)

總結(jié) 

到此這篇關(guān)于Python的協(xié)程操作幾種實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)Python協(xié)程操作內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python輪子使用之.whl原理與安裝完整指南

    Python輪子使用之.whl原理與安裝完整指南

    WHL文件是以Wheel格式保存的Python安裝包,Wheel是Python發(fā)行版的標(biāo)準(zhǔn)內(nèi)置包格式,這篇文章主要介紹了Python輪子使用之.whl原理與安裝的相關(guān)資料,需要的朋友可以參考下
    2026-01-01
  • Python繪制地圖神器folium的新人入門(mén)指南

    Python繪制地圖神器folium的新人入門(mén)指南

    folium庫(kù)是一個(gè)用于完成地圖可視化的Python擴(kuò)展庫(kù),下面這篇文章主要給大家介紹了關(guān)于Python繪制地圖神器folium入門(mén)的相關(guān)資料,需要的朋友可以參考下
    2021-05-05
  • 人工智能學(xué)習(xí)pyTorch的ResNet殘差模塊示例詳解

    人工智能學(xué)習(xí)pyTorch的ResNet殘差模塊示例詳解

    這篇文章主要為大家介紹了人工智能學(xué)習(xí)pyTorch的ResNet殘差模塊示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-11-11
  • 如何利用python將一個(gè)py文件變成一個(gè)軟件詳解

    如何利用python將一個(gè)py文件變成一個(gè)軟件詳解

    在我們完成一個(gè)Python項(xiàng)目或一個(gè)程序時(shí),希望將Python的py文件打包成在Windows系統(tǒng)下直接可以運(yùn)行的exe程序,下面這篇文章主要給大家介紹了關(guān)于如何利用python將一個(gè)py文件變成一個(gè)軟件的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • Python繪制七彩花朵(用Turtle)

    Python繪制七彩花朵(用Turtle)

    這篇文章主要給大家介紹了關(guān)于Python使用Turtle繪制七彩花朵的相關(guān)資料,通過(guò)本文介紹的方法就算剛?cè)腴T(mén)的朋友也可以很快的入手繪制出漂亮的七彩花朵,需要的朋友可以參考下
    2023-07-07
  • Python繪制柱狀圖堆疊圖完整代碼

    Python繪制柱狀圖堆疊圖完整代碼

    有個(gè)朋友要求幫忙繪制堆疊柱狀圖,查閱了一些文檔之后也算是完成了,只是一個(gè)小demo,下面我就記錄一下,這篇文章主要給大家介紹了關(guān)于Python繪制柱狀圖堆疊圖的相關(guān)資料,需要的朋友可以參考下
    2023-09-09
  • 淺談優(yōu)化Django ORM中的性能問(wèn)題

    淺談優(yōu)化Django ORM中的性能問(wèn)題

    這篇文章主要介紹了淺談優(yōu)化Django ORM中的性能問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-07-07
  • python2.6.6如何升級(jí)到python2.7.14

    python2.6.6如何升級(jí)到python2.7.14

    這篇文章主要為大家詳細(xì)介紹了python2.6.6如何升級(jí)到python2.7.14,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • Python結(jié)合pywebview打造輕量級(jí)桌面應(yīng)用的完整教學(xué)

    Python結(jié)合pywebview打造輕量級(jí)桌面應(yīng)用的完整教學(xué)

    pywebview 是一個(gè)輕量級(jí)的跨平臺(tái)Python庫(kù),它允許你在一個(gè)原生窗口中嵌入Web技術(shù)來(lái)構(gòu)建GUI界面,下面我們就來(lái)看看Python如何使用pywebview打造輕量級(jí)桌面應(yīng)用吧
    2026-05-05
  • Python中jieba模塊使用方法詳解

    Python中jieba模塊使用方法詳解

    這篇文章主要介紹了Python中jieba模塊使用的相關(guān)資料,jieba是中文自然語(yǔ)言處理中常用的分詞工具,支持精確模式、全模式和搜索引擎模式,它還提供了自定義詞典和TF-IDF、TextRank等關(guān)鍵詞提取方法,需要的朋友可以參考下
    2024-12-12

最新評(píng)論

香河县| 海原县| 山西省| 翼城县| 蒙自县| 安庆市| 抚宁县| 盖州市| 江安县| 抚远县| 平武县| 乌拉特中旗| 嫩江县| 海盐县| 治县。| 兴海县| 伊金霍洛旗| 襄汾县| 伊通| 新安县| 米易县| 竹山县| 临湘市| 尉犁县| 青海省| 永川市| 阳春市| 宜阳县| 和林格尔县| 道真| 保山市| 新宁县| 繁峙县| 台北县| 犍为县| 安平县| 湖南省| 衢州市| 库尔勒市| 楚雄市| 灯塔市|