python實(shí)現(xiàn)協(xié)程的具體示例
協(xié)程(Coroutine)是一種輕量級(jí)的并發(fā)編程技術(shù),它允許程序在某個(gè)點(diǎn)上暫停執(zhí)行,并在稍后恢復(fù)執(zhí)行,而不是像線程那樣在不同的執(zhí)行上下文中切換。Python中的協(xié)程通常使用生成器函數(shù)或async/await關(guān)鍵字來(lái)定義。
生成器函數(shù)實(shí)現(xiàn)協(xié)程:
def simple_coroutine(): print("協(xié)程開(kāi)始") x = yield print("接收到的值:", x) # 創(chuàng)建協(xié)程對(duì)象 coroutine = simple_coroutine() # 啟動(dòng)協(xié)程 next(coroutine) # 發(fā)送值給協(xié)程 coroutine.send(10)
async/await實(shí)現(xiàn)協(xié)程:
import asyncio async def simple_coroutine(): print("協(xié)程開(kāi)始") await asyncio.sleep(1) print("協(xié)程結(jié)束") # 創(chuàng)建事件循環(huán) loop = asyncio.get_event_loop() # 運(yùn)行協(xié)程 loop.run_until_complete(simple_coroutine())
生成器函數(shù)實(shí)現(xiàn):通過(guò)生成器函數(shù)定義的協(xié)程,可以在函數(shù)中使用yield關(guān)鍵字暫停執(zhí)行,等待外部發(fā)送值給它。當(dāng)調(diào)用生成器的send方法時(shí),生成器會(huì)從yield語(yǔ)句處恢復(fù)執(zhí)行,并接收發(fā)送的值。
async/await實(shí)現(xiàn):使用async/await關(guān)鍵字定義的協(xié)程,可以在函數(shù)中使用await關(guān)鍵字暫停執(zhí)行,等待某個(gè)異步操作的完成。當(dāng)使用await關(guān)鍵字等待異步操作時(shí),事件循環(huán)會(huì)繼續(xù)執(zhí)行其他任務(wù),直到異步操作完成后,協(xié)程才會(huì)繼續(xù)執(zhí)行。
Python中的協(xié)程可以用于實(shí)現(xiàn)高效的異步編程,特別適用于I/O密集型的任務(wù)。通過(guò)協(xié)程,可以輕松地編寫(xiě)高效、簡(jiǎn)潔的異步代碼,實(shí)現(xiàn)非阻塞的并發(fā)處理。
在使用協(xié)程時(shí),可以利用 asyncio 模塊來(lái)調(diào)度協(xié)程的執(zhí)行。asyncio 提供了一個(gè)事件循環(huán)(event loop),用于管理協(xié)程的執(zhí)行和調(diào)度。
import asyncio # 定義一個(gè)異步函數(shù) async def print_numbers(): for i in range(1, 6): print(i) # 模擬一個(gè)異步操作,等待0.5秒 await asyncio.sleep(0.5) # 創(chuàng)建事件循環(huán) loop = asyncio.get_event_loop() # 運(yùn)行協(xié)程 loop.run_until_complete(print_numbers())
在這個(gè)示例中,print_numbers 是一個(gè)異步函數(shù),它使用 async def 定義,其中包含了一個(gè)異步操作 await asyncio.sleep(0.5),用于模擬異步任務(wù)。然后通過(guò) run_until_complete 方法運(yùn)行了這個(gè)協(xié)程,使得事件循環(huán)可以調(diào)度它的執(zhí)行。
另外,也可以使用 asyncio.create_task 方法來(lái)在事件循環(huán)中并發(fā)運(yùn)行多個(gè)協(xié)程:
import asyncio async def task1(): print("Task 1 started") await asyncio.sleep(1) print("Task 1 finished") async def task2(): print("Task 2 started") await asyncio.sleep(2) print("Task 2 finished") async def main(): # 并發(fā)運(yùn)行 task1 和 task2 await asyncio.gather(task1(), task2()) # 創(chuàng)建事件循環(huán)并運(yùn)行主協(xié)程 loop = asyncio.get_event_loop() loop.run_until_complete(main())
在這個(gè)示例中,task1 和 task2 是兩個(gè)獨(dú)立的協(xié)程,它們被同時(shí)調(diào)度執(zhí)行,而 main 協(xié)程則使用 asyncio.gather 方法并發(fā)地運(yùn)行了這兩個(gè)協(xié)程。
在Python中,進(jìn)程(Process)、線程(Thread)和協(xié)程(Coroutine)都是用于實(shí)現(xiàn)并發(fā)編程的技術(shù),它們之間有著區(qū)別和聯(lián)系:
進(jìn)程(Process):
進(jìn)程是操作系統(tǒng)分配資源的基本單位,每個(gè)進(jìn)程都有獨(dú)立的內(nèi)存空間和執(zhí)行環(huán)境。
進(jìn)程之間的通信相對(duì)獨(dú)立,通常需要借助進(jìn)程間通信(IPC)機(jī)制,如管道、消息隊(duì)列、共享內(nèi)存等。
在Python中,可以使用 multiprocessing 模塊創(chuàng)建和管理進(jìn)程,每個(gè)進(jìn)程都有自己的全局解釋器鎖(GIL),因此可以充分利用多核CPU。
線程(Thread):
線程是操作系統(tǒng)調(diào)度的最小執(zhí)行單位,同一個(gè)進(jìn)程內(nèi)的多個(gè)線程共享相同的內(nèi)存空間和全局變量。
線程之間的通信相對(duì)容易,可以直接共享全局變量和資源。
在Python中,可以使用 threading 模塊創(chuàng)建和管理線程,由于全局解釋器鎖(GIL)的存在,Python中的線程并不能充分利用多核CPU,適合用于IO密集型任務(wù)。
協(xié)程(Coroutine):
協(xié)程是一種輕量級(jí)的并發(fā)編程技術(shù),它允許程序在某個(gè)點(diǎn)上暫停執(zhí)行,并在稍后恢復(fù)執(zhí)行,而不是像線程那樣在不同的執(zhí)行上下文中切換。
協(xié)程通常使用生成器函數(shù)或async/await關(guān)鍵字來(lái)定義,是在單線程內(nèi)部實(shí)現(xiàn)的,因此不需要像線程那樣涉及操作系統(tǒng)調(diào)度。
在Python中,可以使用 asyncio 模塊來(lái)實(shí)現(xiàn)協(xié)程,它提供了事件循環(huán)(event loop)來(lái)調(diào)度協(xié)程的執(zhí)行,適合用于IO密集型任務(wù)和高并發(fā)的網(wǎng)絡(luò)應(yīng)用。
區(qū)別:
- 資源占用:進(jìn)程是操作系統(tǒng)分配資源的基本單位,擁有獨(dú)立的內(nèi)存空間和執(zhí)行環(huán)境,因此創(chuàng)建和銷毀進(jìn)程的開(kāi)銷較大。線程是進(jìn)程內(nèi)部的執(zhí)行單元,共享相同的內(nèi)存空間和全局變量,創(chuàng)建和銷毀線程的開(kāi)銷較小。協(xié)程是在單個(gè)線程內(nèi)部實(shí)現(xiàn)的,并不需要操作系統(tǒng)調(diào)度,因此占用的資源更少。
- 通信方式:進(jìn)程間通信需要借助操作系統(tǒng)提供的機(jī)制,如管道、消息隊(duì)列等。線程間通信相對(duì)容易,可以直接共享全局變量和資源。協(xié)程間通信通常通過(guò)消息傳遞或共享內(nèi)存等方式實(shí)現(xiàn)。
- 并發(fā)模型:進(jìn)程是重量級(jí)的并發(fā)模型,適用于CPU密集型任務(wù)。線程是輕量級(jí)的并發(fā)模型,適用于IO密集型任務(wù)。協(xié)程是更輕量級(jí)的并發(fā)模型,適用于大量的IO密集型任務(wù)和高并發(fā)的網(wǎng)絡(luò)應(yīng)用。
- 調(diào)度方式:進(jìn)程和線程的調(diào)度由操作系統(tǒng)負(fù)責(zé),具有較高的可靠性和穩(wěn)定性。協(xié)程的調(diào)度由應(yīng)用程序自己控制,可以靈活地調(diào)整執(zhí)行順序和優(yōu)先級(jí)。
聯(lián)系:
- 進(jìn)程、線程和協(xié)程都是用于實(shí)現(xiàn)并發(fā)編程,可以在多個(gè)任務(wù)之間實(shí)現(xiàn)并行執(zhí)行,提高系統(tǒng)的吞吐量和性能。
- 進(jìn)程和線程都是操作系統(tǒng)層面的概念,而協(xié)程是在應(yīng)用程序?qū)用鎸?shí)現(xiàn)的。
- 協(xié)程可以在單個(gè)線程內(nèi)部實(shí)現(xiàn)并發(fā),而不需要操作系統(tǒng)進(jìn)行線程切換,因此具有更高的效率和更少的資源消耗。
- 它們都可以用于處理多任務(wù)、提高系統(tǒng)的響應(yīng)速度和資源利用率。
- 在實(shí)際應(yīng)用中,通常會(huì)根據(jù)任務(wù)的特點(diǎn)和需求選擇合適的并發(fā)模型,或者結(jié)合多種并發(fā)模型來(lái)實(shí)現(xiàn)更復(fù)雜的應(yīng)用場(chǎng)景。
總的來(lái)說(shuō),進(jìn)程、線程和協(xié)程是并發(fā)編程中常用的三種技術(shù),它們各自有著不同的特點(diǎn)和適用場(chǎng)景,可以根據(jù)具體的需求選擇合適的并發(fā)模型。
到此這篇關(guān)于python實(shí)現(xiàn)協(xié)程的具體示例的文章就介紹到這了,更多相關(guān)python 協(xié)程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pytest用例間參數(shù)傳遞的兩種實(shí)現(xiàn)方式示例
pytest提供了許多運(yùn)行命令以供定制化運(yùn)行某一類測(cè)試用例或者某個(gè)測(cè)試用例等,下面這篇文章主要給大家介紹了關(guān)于pytest用例間參數(shù)傳遞的兩種實(shí)現(xiàn)方式,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-12-12Python3二分查找?guī)旌瘮?shù)bisect(),bisect_left()和bisect_right()的區(qū)別
這篇文章主要介紹了Python3二分查找?guī)旌瘮?shù)bisect(),bisect_left()和bisect_right()的區(qū)別,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03Python根據(jù)輸入?yún)?shù)計(jì)算結(jié)果的實(shí)例方法
在本篇文章里小編個(gè)大家整理了一篇關(guān)于Python根據(jù)輸入?yún)?shù)計(jì)算結(jié)果的實(shí)例方法,有興趣的朋友們可以跟著學(xué)習(xí)參考下。2021-08-08python爬取網(wǎng)易云音樂(lè)熱歌榜實(shí)例代碼
在本篇文章里小編給大家整理的是關(guān)于python爬取網(wǎng)易云音樂(lè)熱歌榜實(shí)例代碼,需要的朋友們可以學(xué)習(xí)下。2020-08-08利用Numba與Cython結(jié)合提升python運(yùn)行效率詳解
近些年來(lái), Numba和Cython在數(shù)學(xué)科學(xué)界得到了廣泛的關(guān)注。它們都提供了一種加速CPU密集型任務(wù)的方法,但以不同的方式。本文描述了它們之間體系結(jié)構(gòu)的差異2021-09-09基于telepath庫(kù)實(shí)現(xiàn)Python和JavaScript之間交換數(shù)據(jù)
telepath是一個(gè)Django庫(kù),用于在Python和JavaScript之間交換數(shù)據(jù),使您可以構(gòu)建具有豐富客戶端接口的應(yīng)用程序,同時(shí)將業(yè)務(wù)邏輯保留在服務(wù)器端代碼中。2021-05-05一小時(shí)學(xué)會(huì)TensorFlow2之全連接層
這篇文章主要介紹了TensorFlow2之全連接層,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09python opencv人臉識(shí)別考勤系統(tǒng)的完整源碼
這篇文章主要介紹了python opencv人臉識(shí)別考勤系統(tǒng)的完整源碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04Pandas中的loc與iloc區(qū)別與用法小結(jié)
loc函數(shù):通過(guò)行索引 “Index” 中的具體值來(lái)取行數(shù)據(jù)(如取"Index"為"A"的行)而iloc函數(shù):通過(guò)行號(hào)來(lái)取行數(shù)據(jù)(如取第二行的數(shù)據(jù)),這篇文章介紹Pandas中的loc與iloc區(qū)別與用法,感興趣的朋友一起看看吧2024-01-01