簡體   English   中英

何時使用 asyncio.get_running_loop() 與 asyncio.get_event_loop()?

[英]When to use asyncio.get_running_loop() vs asyncio.get_event_loop()?

我已經看到使用運行阻塞代碼

loop = asyncio.get_running_loop()
await loop.run_in_executor(None, blockingfunc)

loop = asyncio.get_event_loop()
await loop.run_in_executor(None, blockingfunc)

我們什么時候應該使用asyncio.get_running_loop()asyncio.get_event_loop()

asyncio.get_event_loop()具有asyncio.get_running_loop()asyncio.new_event_loop()asyncio.set_event_loop()的特性。

asyncio.get_event_loop()從 3.10 版開始棄用

獲取當前事件循環。

如果當前OS線程沒有設置current event loop,OS線程是main,set_event_loop()還沒有被調用,asyncio會創建一個新的event loop並設置為current。

asyncio.get_running_loop()

返回當前操作系統線程中正在運行的事件循環。

asyncio.new_event_loop()

創建並返回一個新的事件循環 object。

asyncio.set_event_loop()

將循環設置為當前操作系統線程的當前事件循環

例如,如果運行以下代碼:

import asyncio

async def test():
    while True:
        print("Test")
        await asyncio.sleep(1)

async def call_test():
    loop = asyncio.get_running_loop()
    loop.create_task(test())

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)

loop.create_task(call_test())
loop.run_forever()

每秒打印一次Test

Test
Test
Test
...

所以現在,我們可以在 call_test asyncio.get_event_loop()中將call_test() asyncio.get_running_loop()為 asyncio.get_event_loop() 並將loop = asyncio.new_event_loop()asyncio.set_event_loop(loop)替換為asyncio.get_event_loop() ,如下所示:

import asyncio

async def test():
    while True:
        print("Test")
        await asyncio.sleep(1)

async def call_test():
    loop = asyncio.get_event_loop() # Here
    # loop = asyncio.get_running_loop()
    loop.create_task(test())

loop = asyncio.get_event_loop() # Here
# loop = asyncio.new_event_loop()
# asyncio.set_event_loop(loop)

loop.create_task(call_test())
loop.run_forever()

然后, Test仍然每秒打印一次:

Test
Test
Test
...

所以,關於何時使用asyncio.get_event_loop()asyncio.get_running_loop() ,你不應該在任何時候使用asyncio.get_event_loop()因為它自 version 3.10 以來已被棄用 因此,您應該每次都使用asyncio.get_running_loop()以及asyncio.new_event_loop()asyncio.set_event_loop() 但是如果你真的想使用asyncio.get_event_loop() ,用它來減少代碼。

按照官方文檔get_running_loopget_event_loop都是用來實際獲取一個active loop的,區別在於后者get_event_loop的行為更復雜,因此get_running_loop可以廣泛應用於存在loop的應用中毫無疑問。

此外,在文檔中建議使用run方法來獲取事件循環,例如

async def main():
    await asyncio.sleep(1)
    print('hello')

asyncio.run(main())   

代替:

async def main():
    await asyncio.sleep(1)
    print('hello')
        
loop = asyncio.get_event_loop()
task = loop.create_task(main)
loop.run_forever()

請注意, run方法解決方案在 Jupyter Notebook 中可能會很奇怪。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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