![](/img/trans.png)
[英]Python asyncio run_coroutine_threadsafe never running coroutine?
[英]How to properly use asyncio run_coroutine_threadsafe function?
我正在嘗試理解 asyncio 模塊並花了大約一個小時的時間使用 run_coroutine_threadsafe 函數,我什至來到了工作示例,它按預期工作,但有幾個限制。
首先,我不明白我應該如何在主(任何其他)線程中正確調用 asyncio 循環,在示例中我用run_until_complete
調用它並給它一個協程使其忙於某事,直到另一個線程不會給它一個協程. 我還有哪些其他選擇?
在現實生活中我必須混合異步和線程(在 Python 中)的情況是什么? 由於據我所知 asyncio 應該取代 Python 中的線程(由於 GIL 不是 IO 操作),如果我錯了,請不要生氣並分享您的建議。
Python 版本為 3.7/3.8
import asyncio
import threading
import time
async def coro_func():
return await asyncio.sleep(3, 42)
def another_thread(_loop):
coro = coro_func() # is local thread coroutine which we would like to run in another thread
# _loop is a loop which was created in another thread
future = asyncio.run_coroutine_threadsafe(coro, _loop)
print(f"{threading.current_thread().name}: {future.result()}")
time.sleep(15)
print(f"{threading.current_thread().name} is Finished")
if __name__ == '__main__':
loop = asyncio.get_event_loop()
main_th_cor = asyncio.sleep(10)
# main_th_cor is used to make loop busy with something until another_thread will not send coroutine to it
print("START MAIN")
x = threading.Thread(target=another_thread, args=(loop, ), name="Some_Thread")
x.start()
time.sleep(1)
loop.run_until_complete(main_th_cor)
print("FINISH MAIN")
首先,我不明白我應該如何在主(任何其他)線程中正確調用 asyncio 循環,在示例中我用
run_until_complete
調用它並給它一個協程使其忙於某事,直到另一個線程不會給它一個協程. 我還有哪些其他選擇?
這是loop.run_forever()
一個很好的用例。 該循環將運行並為您使用run_coroutine_threadsafe
提交的協程提供服務。 (你甚至可以從多個線程並行提交這樣的協程;你永遠不需要實例化一個以上的事件循環。)
您可以通過調用loop.call_soon_threadsafe(loop.stop)
從不同的線程停止循環。
在現實生活中我必須混合異步和線程(在 Python 中)的情況是什么?
理想情況下應該沒有。 但在現實世界中,它們確實會出現。 例如:
當您將 asyncio 引入現有的大型程序時,該程序使用線程和阻塞調用並且不能一次全部轉換為 asyncio。 run_coroutine_threadsafe
允許常規阻塞代碼使用 asyncio。
當您處理舊的“異步”API 時,這些 API 在后台使用線程並從其他線程調用用戶提供的 API。 有很多例子,比如 Python 自帶的multiprocessing
。
當您需要從 asyncio 調用沒有異步等效項的阻塞函數時 - 例如 CPU 綁定函數、遺留數據庫驅動程序等。 這不是run_coroutine_threadsafe
的用例,在這里您將使用run_in_executor
,但它是混合線程和 asyncio 的另一個示例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.