簡體   English   中英

如何正確使用 asyncio run_coroutine_threadsafe 函數?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM