您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關Python中的asyncio庫-線程同步,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
前面的代碼都是異步的,就如sleep,需要用asyncio.sleep而不是阻塞的time.sleep,如果有同步邏輯,怎么利用asyncio實現并發呢?答案是用run_in_executor。在一開始我說過開發者創建 Future 對象情況很少,主要是用run_in_executor,就是讓同步函數在一個執行器( executor)里面運行。
同步代碼
def a(): time.sleep(1) return 'A' async def b(): await asyncio.sleep(1) return 'B' def show_perf(func): print('*' * 20) start = time.perf_counter() asyncio.run(func()) print(f'{func.__name__} Cost: {time.perf_counter() - start}') async def c1(): loop = asyncio.get_running_loop() await asyncio.gather( loop.run_in_executor(None, a), b() ) In : show_perf(c1) ******************** c1 Cost: 1.0027242230000866
可以看到用run_into_executor可以把同步函數邏輯轉化成一個協程,且實現了并發。這里要注意細節,就是函數a是普通函數,不能寫成協程,下面的定義是錯誤的,不能實現并發:
async def a(): time.sleep(1) return 'A'
因為 a 里面沒有異步代碼,就不要用async def來定義。需要把這種邏輯用loop.run_in_executor封裝到協程:
async def c(): loop = asyncio.get_running_loop() return await loop.run_in_executor(None, a)
大家理解了吧?
loop.run_in_executor(None, a)這里面第一個參數是要傳遞concurrent.futures.Executor實例的,傳遞None會選擇默認的executor:
In : loop._default_executor Out: <concurrent.futures.thread.ThreadPoolExecutor at 0x112b60e80>
當然我們還可以用進程池,這次換個常用的文件讀寫例子,并且用:
async def c3(): loop = asyncio.get_running_loop() with concurrent.futures.ProcessPoolExecutor() as e: print(await asyncio.gather( loop.run_in_executor(e, a), b() )) In : show_perf(c3) ******************** ['A', 'B'] c3 Cost: 1.0218078890000015
看完上述內容,你們對Python中的asyncio庫-線程同步有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。