asyncio (並行計算)
- 2025.01.01
- asyncio
asyncio1Python 3.13.1 Doc.: asyncio: Library for writing concurrent2WIKI: Concurrent Computing code.
async / await
3.5 版前
async def
函數內無法使用yield
或 yield from
會引發
SyntaxError
錯誤
3.6 版以後有了 Asynchronous Generators 而可以使用
yield
使用例
import asyncio import time async def say_after(delay, what): await asyncio.sleep(delay) print(what) async def main(): print(f"started at {time.strftime('%X')}") await say_after(1, 'hello') await say_after(2, 'world') print(f"finished at {time.strftime('%X')}") asyncio.run(main())
預期輸出
started at 17:13:52
hello
world
finished at 17:13:55
用 asyncio.create_task() 改寫 main()
await func(...)
⇒ task = asyncio.create_task(func(...))
+ await task
async def main(): task_1 = asyncio.create_task( say_after(1, 'hello') ) task_2 = asyncio.create_task( say_after(2, 'world') ) print(f"started at {time.strftime('%X')}") await task_1 await task_2 print(f"finished at {time.strftime('%X')}") asyncio.run(main())
用 asyncio.TaskGroup() (since ver. 3.11) 改寫 main()
task = asyncio.create_task(func(...))
-
await task⇒await
已經包含在 context manager3Python Doc.: With Statement Context Managers4Python Doc.: The with statement 中
async def main(): async with asyncio.TaskGroup() as tg: task_1 = tg.create_task( say_after(1, 'hello') ) task_2 = tg.create_task( say_after(2, 'world') ) print(f"started at {time.strftime('%X')}") # The await is implicit when the context manager exits. print(f"finished at {time.strftime('%X')}") asyncio.run(main())
Awaitables
We say that an object is an awaitable object if it can be used in an await expression. Many asyncio APIs are designed to accept awaitables.
There are three main types of awaitable objects: coroutines, Tasks, and Futures.
Coroutines 協程
-
A coroutine function: An
async def
function. -
A coroutine object: An object returned by calling a coroutine function.
Tasks
When a coroutine is wrapped into a Task with functions like asyncio.create_task() the coroutine is automatically scheduled to run soon:
Task Object
Creating Tasks
Task Cancellation
Task Groups
Terminating a Task Group
Sleeping
Running Tasks Concurrently
Eager Task Factory
Shielding From Cancellation
Timeouts
Waiting Primitives
coroutine asyncio.wait(aws, *, timeout=None, return_when=ALL_COMPLETED)

- Run
Future
andTask
instances in theaws
iterable concurrently and block until the condition specified byreturn_when
. - The
aws
iterable must not be empty. - Returns two sets of Tasks/Futures:
(done, pending)
.
ex:done, pending = await asyncio.wait(aws)
timeout
(afloat
orint
), if specified, can be used to control the maximum number of seconds to wait before returning.Note that this function does not raise TimeoutError. Futures or Tasks that aren’t done when the timeout occurs are simply returned in the second set.
return_when
indicates when this function shouldreturn
.
It must be one of the following constants:- asyncio.FIRST_COMPLETED:
The function will return when any future finishes or is cancelled. -
asyncio.FIRST_EXCEPTION:
The function will return when any future finishes by raising an exception. If no future raises an exception then it is equivalent to ALL_COMPLETED. -
asyncio.ALL_COMPLETED:
The function will return when all futures finish or are cancelled
- asyncio.FIRST_COMPLETED:
- Unlike
wait_for()
,wait()
does not cancel the futures when a timeout occurs.
asyncio.as_completed(aws, *, timeout=None)

[async ]for task in as_completed(tasks):
result = await task
...
Running in Threads
Scheduling From Other Threads
Introspection
Futures
Last Updated on 2025/01/01 by A1go