4.1 Phương thức run()
Module asyncio
cung cấp nhiều phương thức và hàm
để tạo và quản lý các chương trình bất đồng bộ. Đây là một số
phương thức và hàm phổ biến nhất và thường được sử dụng của module asyncio
.
Hôm nay chúng ta sẽ xem xét 4 phương thức phổ biến nhất:
run()
sleep()
wait()
gather()
Bây giờ là chi tiết hơn:
Phương thức asyncio.run(coroutine)
Phương thức này được sử dụng để chạy một chương trình bất đồng bộ. Nó đặc biệt hữu ích khi bạn muốn chạy mã bất đồng bộ từ một ngữ cảnh đồng bộ, chẳng hạn như từ luồng chính của chương trình.
Phương thức asyncio.run()
khởi chạy coroutine chính và quản lý
việc tạo và đóng vòng lặp sự kiện. Phương thức này tự động tạo ra một
vòng lặp sự kiện mới và kết thúc nó khi coroutine hoàn thành.
Chữ ký:
asyncio.run(async_function(), *, debug=False)
-
async_function
: Coroutine cần được thực thi. -
debug
: Tham số tùy chọn, bật chế độ gỡ lỗi cho vòng lặp sự kiện.
Ví dụ sử dụng:
import asyncio
async def main():
print('Hello')
await asyncio.sleep(1)
print('World')
asyncio.run(main())
Giới hạn
Không thể được gọi từ bên trong một vòng lặp sự kiện khác:
asyncio.run()
chỉ nên được gọi từ mã đồng bộ,
vì nó tạo và kết thúc vòng lặp sự kiện riêng của mình. Nếu
cố gắng gọi nó từ bên trong một vòng lặp sự kiện đã tồn tại, điều này sẽ gây ra
lỗi.
Chỉ phù hợp cho cấp cao nhất:
Phương thức này được thiết kế để khởi chạy mục nhập chính của chương trình và không nên được sử dụng cho các lời gọi lồng của các hàm bất đồng bộ.
4.2 Phương thức sleep()
Phương thức này được sử dụng khi bạn cần tạm dừng thực thi coroutine trong một thời gian nhất định, mà không chặn thực thi của các coroutine khác.
Phương thức asyncio.sleep()
trong module asyncio
được sử dụng để
tạm dừng thực thi coroutine hiện tại trong một số giây nhất định.
Phương thức này khác với phương thức tương tự time.sleep()
ở chỗ
cho phép các tác vụ khác chạy trong thời gian tạm dừng. Điều này làm cho nó
hữu ích cho việc viết các chương trình bất đồng bộ, yêu cầu trễ hoặc
chờ đợi mà không chặn luồng chính.
Chữ ký:
asyncio.sleep(delay, result=None)
-
delay
: Thời gian trễ tính bằng giây (có thể là số thập phân). -
result
: Kết quả tùy chọn, sẽ được trả về sau khi hoàn thành khoảng trễ.
Ví dụ sử dụng:
import asyncio
async def main():
print('Start sleeping')
await asyncio.sleep(2)
print('Wake up')
asyncio.run(main())
Trong ví dụ này, coroutine main
tạm dừng trong 2 giây, cho phép
các tác vụ khác chạy trong thời gian này, sau đó tiếp tục và in ra "Wake
up".
4.3 Phương thức wait()
Phương thức này hữu ích khi bạn cần chờ đến khi nhiều thao tác bất đồng bộ hoàn tất, nhưng bạn muốn có sự kiểm soát tinh tế hơn đối với quá trình chờ đợi.
Phương thức asyncio.wait()
trong module asyncio
cho phép chờ
đợi nhiều tác vụ bất đồng bộ hoặc coroutine hoàn tất. Có thể chờ đợi
tất cả các tác vụ hoàn tất, tác vụ đầu tiên hoàn tất hoặc một tác vụ nào đó hoàn tất với lỗi.
Khác với gather()
, phương thức wait()
cung cấp kiểm soát nhiều hơn đối với quá trình chờ đợi, cho phép đặt thời gian chờ và điều kiện hoàn thành.
Các đặc điểm chính của phương thức asyncio.wait()
Chữ ký:
asyncio.wait(fs, *, timeout=None, return_when=ALL_COMPLETED)
Trong đó:
-
fs
: Bộ sưu tập các đối tượngFuture
hoặc coroutine cần được chờ đợi. -
timeout
: Tham số tùy chọn, chỉ định thời gian chờ tối đa tính bằng giây. Nếu thời gian chờ hết hạn, phương thức sẽ trả về các tác vụ đã hoàn tất tại thời điểm đó. -
return_when
: Điều kiện xác định khi nào phương thức nên hoàn tất. Các giá trị có thể:-
ALL_COMPLETED
: Phương thức trả về kết quả, khi tất cả các tác vụ đã hoàn tất (mặc định). -
FIRST_COMPLETED
: Phương thức trả về kết quả, khi tác vụ đầu tiên hoàn tất. -
FIRST_EXCEPTION
: Phương thức trả về kết quả, khi tác vụ nào đó hoàn tất với lỗi.
-
Chờ hoàn tất nhiều tác vụ hoặc coroutine. Có thể chỉ định thời gian chờ và điều kiện hoàn tất.
import asyncio
async def say(what, delay):
await asyncio.sleep(delay)
return what
async def main():
task1 = asyncio.create_task(say('hello', 1))
task2 = asyncio.create_task(say('world', 2))
done, pending = await asyncio.wait([task1, task2], timeout=1.5)
for task in done:
print(task.result())
asyncio.run(main())
Trong ví dụ trên, chúng ta bọc mỗi coroutine say()
trong một đối tượng Task
bằng cách
gọi phương thức create_task()
, và sau đó truyền danh sách các task này vào phương thức
wait()
. Các đối tượng Task
cho phép thực thi các coroutine song song, không cần chờ một cái hoàn tất trước khi chạy cái khác.
Phương thức wait
sẽ chỉ chờ thực hiện các task trong một giây rưỡi, sau đó
trả về một tuple của các task: giá trị đầu tiên của tuple sẽ chứa các tác vụ
đã hoàn tất (done)
, thứ hai là các tác vụ đang trong quá trình
(pending)
.
4.4 Phương thức gather()
Phương thức này đặc biệt hữu ích khi bạn cần khởi chạy nhiều thao tác bất đồng bộ song song và lấy kết quả của chúng dưới dạng danh sách.
Phương thức asyncio.gather()
trong module asyncio
được sử dụng để
thực hiện nhiều tác vụ bất đồng bộ song song và trả về kết quả của chúng dưới dạng danh sách. Đây là một cách tiện lợi để nhóm các coroutine hoặc
task và chờ đợi chúng hoàn tất.
Các đặc điểm chính của phương thức asyncio.gather()
Chữ ký:
asyncio.gather(*coros_or_futures, return_exceptions=False)
Trong đó:
-
coros_or_futures
: Các coroutine hoặc đối tượngFuture
cần được thực hiện. -
return_exceptions
: Giá trị boolean, chỉ rõ liệu các lỗi có được trả về dưới dạng kết quả hay không. Mặc định làFalse
.
Ví dụ sử dụng
import asyncio
async def say_after(delay, what):
await asyncio.sleep(delay)
return what
async def main():
results = await asyncio.gather(
say_after(1, 'hello'),
say_after(2, 'world')
)
print(results)
asyncio.run(main())
Ví dụ này cho thấy cách asyncio.gather
có thể được
sử dụng để thực hiện song song nhiều tác vụ, mỗi tác vụ có
độ trễ riêng của nó. Kết quả của tất cả các tác vụ được trả về dưới dạng danh sách. Khác với wait
, gather
không chỉ chờ đợi các task hoàn tất, mà còn thu thập kết quả của tất cả các coroutine, điều này làm cho nó tiện lợi khi kết quả thực hiện của từng task quan trọng.
GO TO FULL VERSION