+1

Mã bất đồng bộ là gì? Cách sử dụng nó trong Python để tăng tốc mã của bạn

Bạn đã bao giờ nghe đến thuật ngữ "asynchronous" (bất đồng bộ) được các lập trình viên nhắc đến như một thứ gì đó vô cùng kỳ diệu hay không? Hôm nay, chúng ta sẽ cùng nhau khám phá bí mật của asynchronous code trong Python, lý do tại sao nó lại tuyệt vời đến vậy và cách sử dụng nó để tăng tốc độ cho code của bạn.

Code đồng bộ & bất đồng bộ: Rùa và thỏ trong thế giới lập trình

1. Synchronous Code (Code đồng bộ)

Synchronous code chạy theo từng dòng. Ví dụ, nếu bạn đang lấy dữ liệu thời tiết cho Paris và London, code của bạn sẽ lấy dữ liệu của Paris trước, sau đó chờ cho đến khi hoàn thành rồi mới chuyển sang lấy dữ liệu của London. Điều này khiến code của bạn dễ đọc hơn, nhưng nó lại chậm vì nó phải chờ đợi trong khi mỗi yêu cầu được hoàn thành. Không lý tưởng một chút nào!

def get_weather_sync(city):
    # Imagine this function fetches weather data for a city
    print(f"Getting weather data for {city}...")
    # Pretend we wait here for the data
    time.sleep(2)
    print(f"Got data for {city}!")

get_weather_sync("Paris")
get_weather_sync("London")

Ở đây, mỗi thành phố mất 2 giây, do đó việc lấy dữ liệu cho cả hai sẽ mất tổng cộng 4 giây.

2. Asynchronous Code (Code bất đồng bộ)

Asynchronous code không mất thời gian phải chờ đợi! Nếu nó đang lấy dữ liệu thời tiết cho Paris, nó cũng có thể bắt đầu lấy dữ liệu thời tiết cho London cùng một lúc. Nó giống như việc bạn có hai cánh tay: bạn có thể lấy hai thứ cùng một lúc thay vì một. Đây là lúc thư viện asyncio của Python phát huy tác dụng, cho phép bạn xử lý các tác vụ đồng thời.

Dưới đây là một ví dụ đơn giản về asynchronous code:

import asyncio

async def get_weather_async(city):
    print(f"Getting weather data for {city}...")
    await asyncio.sleep(2)
    print(f"Got data for {city}!")

async def main():
    await asyncio.gather(
        get_weather_async("Paris"),
        get_weather_async("London")
    )

asyncio.run(main())

Giờ đây, cả hai tác vụ đều được hoàn thành trong 2 giây thay vì 4 giây. Thật nhanh chóng và tiết kiệm thời gian hơn nhiều phải không nào?

Tại sao nên sử dụng Code bất đồng bộ trong Python?

Asynchronous code phát huy sức mạnh khi bạn đang xử lý các tác vụ I/O-bound. Các tác vụ này dành nhiều thời gian để chờ đợi, chẳng hạn như lấy dữ liệu qua internet. Với asynchronous code, chương trình của bạn có thể thực hiện các hành động khác trong khi chờ đợi, giúp nó nhanh hơn và hiệu quả hơn.

Thư viện asyncio: Trợ thủ đắc lực cho Code bất đồng bộ

Thư viện asyncio của Python cho phép bạn viết asynchronous code với một số công cụ mạnh mẽ:

  • async def: Định nghĩa một hàm bất đồng bộ.
  • await: Tạm dừng hàm cho đến khi tác vụ được chờ đợi hoàn thành.
  • asyncio.gather(): Chạy nhiều hàm async cùng một lúc.

Thử xây dựng một ứng dụng dự báo thời tiết đơn giản nhé

Chúng ta sẽ tạo thử một ứng dụng dự báo thời tiết đơn giản, lấy dữ liệu cho nhiều thành phố đồng thời dựa trên những gì đã đề cập trong bài viết này nhé.

Bước 1: Cài đặt

Đầu tiên, bạn cần cài đặt thư viện aiohttp, giúp bạn thực hiện các yêu cầu HTTP bất đồng bộ. Mở terminal và chạy:

pip install aiohttp

Bước 2: Viết trình lấy dữ liệu thời tiết bất đồng bộ

Chúng ta sẽ sử dụng API thời tiết miễn phí wttr.in, cung cấp thông tin thời tiết chỉ bằng cách gọi một URL.

import asyncio
import aiohttp

async def fetch_weather(session, city):
    url = f"http://wttr.in/{city}?format=3"
    async with session.get(url) as response:
        data = await response.text()
        print(f"Weather in {city}: {data}")

Dưới đây là những gì đang diễn ra:

  • Chúng ta đang sử dụng aiohttp.ClientSession() để tạo một phiên cho các yêu cầu của mình.
  • Dòng await response.text() tạm dừng hàm của chúng ta cho đến khi dữ liệu được trả về.

Bước 3: Chạy các hàm Async cùng nhau

Bây giờ, hãy thêm hàm main, hàm này sẽ lấy dữ liệu thời tiết cho nhiều thành phố đồng thời.

async def main():
    cities = ["Paris", "London", "New York", "Tokyo", "Sydney"]

    async with aiohttp.ClientSession() as session:
        tasks = [fetch_weather(session, city) for city in cities]
        await asyncio.gather(*tasks)

# Start the async event loop
asyncio.run(main())

Trong hàm main:

  • Chúng ta tạo một danh sách các tác vụ cho mỗi thành phố.
  • asyncio.gather(*tasks) chạy tất cả chúng cùng một lúc, do đó ứng dụng thời tiết của chúng ta sẽ lấy dữ liệu cực nhanh!

Bước 4: Chạy ứng dụng của bạn

Lưu code của bạn và sau đó chạy nó! Bạn sẽ thấy thời tiết cho tất cả các thành phố được in ra trong khoảng 2 giây. Dưới đây là toàn bộ code để bạn tiện theo dõi:

import asyncio

import aiohttp



async def fetch_weather(session, city):

    url = f"http://wttr.in/{city}?format=3"

    async with session.get(url) as response:

        data = await response.text()

        print(f"Weather in {city}: {data}")



async def main():

    cities = ["Paris", "London", "New York", "Tokyo", "Sydney"]

    async with aiohttp.ClientSession() as session:

        tasks = [fetch_weather(session, city) for city in cities]

        await asyncio.gather(*tasks)



asyncio.run(main())

Kết luận

Và đó là tất cả! Bạn vừa tạo ra một ứng dụng thời tiết siêu tốc bằng cách sử dụng asynchronous code trong Python. Giờ đây, bạn có thể lấy dữ liệu từ nhiều nguồn mà không làm chậm chương trình của mình, giống như một chuyên gia thực thụ!

Bằng cách học cách sử dụng asyncio, bạn đã mở khóa sức mạnh của code nhanh hơn và hiệu quả hơn. Vậy nên, hãy tiếp tục khám phá thêm nhiều API, xử lý nhiều dữ liệu hơn và xây dựng những thứ tuyệt vời. Cảm ơn các bạn đã theo dõi.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí