簡體   English   中英

Python協程不與time.sleep()並發運行嗎?

[英]Python coroutines don't run concurrently with time.sleep()?

我正在嘗試遵循https://docs.python.org/3/library/asyncio-task.html#coroutines上的示例; 這是同時運行兩個say_after協程的代碼段:

import asyncio
import time


async def say_after(delay, what):
    await asyncio.sleep(delay)
    # time.sleep(delay)
    print(what)


async def main():
    task1 = asyncio.create_task(say_after(1, 'hello'))
    task2 = asyncio.create_task(say_after(2, 'world'))


    print(f"Started at {time.strftime('%X')}")

    await task1
    await task2

    print(f"Finished at {time.strftime('%X')}")


if __name__ == "__main__":
    asyncio.run(main())

如果運行此命令,則開始和結束相隔兩秒:

Started at 12:59:35
hello
world
Finished at 12:59:37

但是,如果我將await asyncio.sleep(delay)替換為await asyncio.sleep(delay) time.sleep(delay)上面的代碼段中的注釋行),我發現它們相距三秒鍾,因此實際上是同步運行的:

Started at 13:00:53
hello
world
Finished at 13:00:56

我不太明白。 即使任務本身包含同步代碼,讓它們並行運行並發任務也沒有意義嗎? 為什么這個例子不再與工作time.sleep()代替asyncio.sleep()

我不太明白。 即使任務本身包含同步代碼,讓它們並行運行並發任務也沒有意義嗎?

並發!=並行。 在編寫asyncio代碼時,底層例程仍必須讓流返回asyncio ,以允許並發。 無論如何,GIL仍然在那里。

為什么此示例不再使用time.sleep()而不是asyncio.sleep()?

asyncio.sleep掛起當前任務,從而允許其他任務運行。 time.sleep並非如此,它是一個阻塞調用(“阻塞”意味着它阻塞了主線程中的執行,並且使用asyncio的程序仍然是單線程的)。

協程提供協作並發 ,而不是並行性。

為了通過協程實現良好的並發性,必須以非阻塞方式編寫在asyncio.run調用的任何代碼。 實際上,這意味着在任務中運行的任何代碼都有責任在適當的時候暫停執行信號,例如:“我沒有做任何有用的事情,因為我正在等待I / O ...”-這允許另一個任務使用事件循環。

暫無
暫無

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

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