PYTHON CONCURRENCY
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

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ả.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

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.

Screenshot 202024 07 26 20231153 png

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.

Screenshot 202024 07 26 20231220 png

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

Screenshot 202024 07 26 20231233 png

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.

Cùng chuyên mục:

Hướng dẫn xây dựng Command-Line Interface (CLI) bằng Quo trong Python

Hướng dẫn xây dựng Command-Line Interface (CLI) bằng Quo trong Python

Hướng dẫn toàn diện về module datetime trong Python

Hướng dẫn toàn diện về module datetime trong Python

Cách truy cập và thiết lập biến môi trường trong Python

Cách truy cập và thiết lập biến môi trường trong Python

Lớp dữ liệu (Data Classes) trong Python với decorator @dataclass

Lớp dữ liệu (Data Classes) trong Python với decorator @dataclass

Từ khóa yield trong Python

Từ khóa yield trong Python

Sự khác biệt giữa sort() và sorted() trong Python

Sự khác biệt giữa sort() và sorted() trong Python

Sử dụng Poetry để quản lý dependencies trong Python

Sử dụng Poetry để quản lý dependencies trong Python

Định dạng chuỗi Strings trong Python

Định dạng chuỗi Strings trong Python

Một tác vụ phổ biến khi làm việc với danh sách trong Python

Một tác vụ phổ biến khi làm việc với danh sách trong Python

Làm việc với các biến môi trường trong Python

Làm việc với các biến môi trường trong Python

Sự khác biệt giữa set() và frozenset() trong Python

Sự khác biệt giữa set() và frozenset() trong Python

Sự khác biệt giữa iterator và iterable trong Python

Sự khác biệt giữa iterator và iterable trong Python

Cách làm việc với file tarball/tar trong Python

Cách làm việc với file tarball/tar trong Python

Chuyển đổi kiểu dữ liệu trong Python

Chuyển đổi kiểu dữ liệu trong Python

Sự khác biệt giữa toán tử == và is trong Python

Sự khác biệt giữa toán tử == và is trong Python

Làm việc với file ZIP trong Python

Làm việc với file ZIP trong Python

Cách sử dụng ThreadPoolExecutor trong Python

Cách sử dụng ThreadPoolExecutor trong Python

Sự khác biệt giữa byte objects và string trong Python

Sự khác biệt giữa byte objects và string trong Python

Xử lý độ chính xác các hàm floor, ceil, round, trunc, format  trong Python

Xử lý độ chính xác các hàm floor, ceil, round, trunc, format trong Python

Cách lặp qua nhiều list với hàm zip() trong Python

Cách lặp qua nhiều list với hàm zip() trong Python

Top