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:

Cách sử dụng lớp QTreeWidget của PyQt

Cách sử dụng lớp QTreeWidget của PyQt

Cách sử dụng lớp QTableWidget để tạo một bảng

Cách sử dụng lớp QTableWidget để tạo một bảng

Cách sử dụng lớp QListWidget trong Python

Cách sử dụng lớp QListWidget trong Python

Cách dùng lớp QStatusBar trong PyQt để tạo thanh status bar

Cách dùng lớp QStatusBar trong PyQt để tạo thanh status bar

Cách dùng lớp QDockWidget của PyQt để tạo một widget

Cách dùng lớp QDockWidget của PyQt để tạo một widget

Cách dùng lớp PyQt QToolBar để tạo các widget toolbar

Cách dùng lớp PyQt QToolBar để tạo các widget toolbar

Cách sử dụng lớp PyQt QMenu để tạo menu

Cách sử dụng lớp PyQt QMenu để tạo menu

Cách sử dụng lớp QMainWindow của PyQt để tạo cửa sổ

Cách sử dụng lớp QMainWindow của PyQt để tạo cửa sổ

Cách dùng lớp PyQt QFileDialog để tạo hộp thoại chọn file

Cách dùng lớp PyQt QFileDialog để tạo hộp thoại chọn file

Cách dùng lớp PyQt QInputDialog để tạo một hộp thoại nhập liệu

Cách dùng lớp PyQt QInputDialog để tạo một hộp thoại nhập liệu

Cách sử dụng lớp PyQt QMessageBox để tạo một hộp thoại

Cách sử dụng lớp PyQt QMessageBox để tạo một hộp thoại

Cách sử dụng lớp PyQt QProgressBar để tạo một widget progress bar

Cách sử dụng lớp PyQt QProgressBar để tạo một widget progress bar

Cách dùng lớp PyQt QTextEdit để tạo một widget cho phép chỉnh sửa

Cách dùng lớp PyQt QTextEdit để tạo một widget cho phép chỉnh sửa

Cách dùng lớp PyQt QGroupBox để tạo một khung nhóm với tiêu đề

Cách dùng lớp PyQt QGroupBox để tạo một khung nhóm với tiêu đề

Cách dùng lớp PyQt QTabWidget để tạo một widget dạng tab

Cách dùng lớp PyQt QTabWidget để tạo một widget dạng tab

Cách dùng PyQt QWidget để làm container chứa các widget khác.

Cách dùng PyQt QWidget để làm container chứa các widget khác.

Cách sử dụng lớp PyQt QSlider để tạo một widget thanh trượt (slider).

Cách sử dụng lớp PyQt QSlider để tạo một widget thanh trượt (slider).

Cách tạo một widget nhập ngày và giờ sử dụng PyQt QDateTimeEdit

Cách tạo một widget nhập ngày và giờ sử dụng PyQt QDateTimeEdit

Cách tạo một widget nhập giờ sử dụng lớp PyQt QTimeEdit

Cách tạo một widget nhập giờ sử dụng lớp PyQt QTimeEdit

Cách tạo một widget nhập ngày sử dụng lớp PyQt QDateEdit

Cách tạo một widget nhập ngày sử dụng lớp PyQt QDateEdit

Top