Thông báo: Download 4 khóa học Python từ cơ bản đến nâng cao tại đây.
Cách sử dụng hàm asyncio.create_task() trong Python
Trong bài viết này, bạn sẽ học cách sử dụng hàm asyncio.create_task()
để chạy nhiều tác vụ đồng thời. Việc sử dụng các tác vụ đồng thời có thể giúp tăng hiệu suất chương trình bằng cách cho phép thực hiện nhiều công việc cùng một lúc mà không cần chờ đợi các thao tác dài hoàn thành. Bạn sẽ thấy cách mô phỏng các thao tác dài, tạo và quản lý các task, và chạy nhiều task đồng thời một cách hiệu quả.
Mô phỏng một thao tác dài trong Python
Để mô phỏng một thao tác dài, bạn có thể sử dụng coroutine sleep() của gói asyncio. Hàm sleep() sẽ trì hoãn một số giây đã chỉ định:
await asyncio.sleep(seconds)
Vì sleep() là một coroutine, bạn cần sử dụng từ khóa await. Ví dụ, đoạn mã sau đây sử dụng coroutine sleep() để mô phỏng một cuộc gọi API:
import asyncio async def call_api(message, result=1000, delay=3): print(message) await asyncio.sleep(delay) return result
Hàm call_api() là một coroutine. Nó hiển thị một thông báo, tạm dừng một số giây (mặc định là ba giây) và trả về một kết quả.
Bài viết này được đăng tại [free tuts .net]
Đoạn mã sau sử dụng hàm call_api() hai lần và đo thời gian hoàn thành:
import asyncio import time async def call_api(message, result=1000, delay=3): print(message) await asyncio.sleep(delay) return result async def main(): start = time.perf_counter() price = await call_api('Get stock price of GOOG...', 300) print(price) price = await call_api('Get stock price of APPL...', 400) print(price) end = time.perf_counter() print(f'It took {round(end-start,0)} second(s) to complete.') asyncio.run(main())
Kết quả:
Get stock price of GOOG... 300 Get stock price of APPL... 400 It took 6.0 second(s) to complete.
Cách hoạt động
Trong coroutine main(), ta thực hiện các bước sau:
Bắt đầu bộ đếm thời gian để đo thời gian hoàn thành:
start = time.perf_counter()
Gọi coroutine call_api() và hiển thị kết quả:
price = await call_api('Get stock price of GOOG...', 300) print(price)
Gọi coroutine call_api() lần thứ hai:
price = await call_api('Get stock price of APPL...', 400) print(price)
Hiển thị thời gian chương trình hoàn thành:
end = time.perf_counter() print(f'It took {round(end-start,0)} second(s) to complete.')
Vì mỗi lần gọi call_api() mất ba giây và gọi hai lần tổng cộng mất sáu giây.
Trong ví dụ này, chúng ta gọi trực tiếp coroutine mà không đặt nó vào vòng lặp sự kiện để chạy. Thay vào đó, chúng ta nhận một đối tượng coroutine và sử dụng từ khóa await để thực thi và nhận kết quả.
Giới thiệu về Task trong Python
Task là một lớp bọc của coroutine, giúp sắp xếp coroutine để chạy trên vòng lặp sự kiện ngay khi có thể. Việc sắp xếp và thực thi diễn ra theo cách không chặn. Bạn có thể tạo một task và thực thi mã khác ngay lập tức trong khi task đang chạy.
Để tạo một task, bạn truyền một coroutine vào hàm create_task() của gói asyncio. Hàm create_task() trả về một đối tượng Task.
Ví dụ sau minh họa cách tạo hai task để sắp xếp và thực thi coroutine call_api():
import asyncio import time async def call_api(message, result=1000, delay=3): print(message) await asyncio.sleep(delay) return result async def main(): start = time.perf_counter() task_1 = asyncio.create_task( call_api('Get stock price of GOOG...', 300) ) task_2 = asyncio.create_task( call_api('Get stock price of APPL...', 300) ) price = await task_1 print(price) price = await task_2 print(price) end = time.perf_counter() print(f'It took {round(end-start,0)} second(s) to complete.') asyncio.run(main())
Kết quả:
Get stock price of GOOG... Get stock price of APPL... 300 300 It took 3.0 second(s) to complete.
Cách hoạt động
Bắt đầu bộ đếm thời gian:
start = time.perf_counter()
Tạo một task và sắp xếp nó để chạy trên vòng lặp sự kiện ngay lập tức:
task_1 = asyncio.create_task( call_api('Get stock price of GOOG...', 300) )
Tạo một task khác và sắp xếp nó để chạy trên vòng lặp sự kiện ngay lập tức:
task_2 = asyncio.create_task( call_api('Get stock price of APPL...', 400) )
Chờ task hoàn thành:
price = await task_1 print(price) price = await task_2 print(price)
Nếu không sử dụng từ khóa await, Python sẽ sắp xếp task để chạy nhưng sẽ dừng lại khi asyncio.run() tắt vòng lặp sự kiện.
Chạy các tác vụ khác trong khi chờ đợi
Khi call_api đang chạy, bạn có thể thực hiện các tác vụ khác. Ví dụ sau hiển thị một thông báo mỗi giây trong khi chờ đợi các task call_api:
import asyncio import time async def call_api(message, result=1000, delay=3): print(message) await asyncio.sleep(delay) return result async def show_message(): for _ in range(3): await asyncio.sleep(1) print('API call is in progress...') async def main(): start = time.perf_counter() message_task = asyncio.create_task( show_message() ) task_1 = asyncio.create_task( call_api('Get stock price of GOOG...', 300) ) task_2 = asyncio.create_task( call_api('Get stock price of APPL...', 300) ) price = await task_1 print(price) price = await task_2 print(price) await message_task end = time.perf_counter() print(f'It took {round(end-start,0)} second(s) to complete.') asyncio.run(main())
Kết quả:
Get stock price of GOOG... Get stock price of APPL... API call is in progress... API call is in progress... API call is in progress... 300 300
Kết bài
Task là một lớp bọc của coroutine giúp sắp xếp coroutine để chạy trên vòng lặp sự kiện ngay khi có thể. Sử dụng hàm create_task()
của thư viện asyncio để tạo một task. Cuối cùng, sử dụng từ khóa await
với task tại một điểm nào đó trong chương trình để đảm bảo rằng task có thể hoàn thành trước khi vòng lặp sự kiện bị đóng bởi hàm asyncio.run()
. Với kiến thức này, bạn có thể tận dụng tối đa khả năng chạy đồng thời các tác vụ trong Python, giúp cải thiện hiệu suất và tối ưu hóa thời gian thực thi của các chương trình phức tạp.