[Learn with Bui] Viết code xử lý bất đồng bộ sử dụng asyncio trong python
Who am I ?
Hello các bạn, mình là Bui - một lập trình viên có 3 năm kinh nghiệm làm việc trong lĩnh vực phát triển phần mềm. Khoảng thời gian không dài nhưng cũng đủ để mình có thể chia sẽ những kiến thức mình học được hy vọng sẽ là những thứ ho, bổ ích cho các bạn hoặc có thể đây chỉ là một cách mình lưu giữ những kiến thức cho thế giới nhỏ bé của riêng mình.
Mở đầu
Xu thế AI hiện nay đang là một trong những thứ khá là nổi bật trong giới công nghệ cũng như những người non-tech. Báo chí, giới truyền thông đã có một cơn sóng lớn sau khi những công nghệ về AI mới như generative AI, chatGPT. Khắp nơi bàn tán về những ‘con’ AI thông minh có thể tự động sinh ra những bức ảnh hay là trả lời bất kì câu hỏi nào chỉ với một câu lệnh (prompt). Đi trước cả những xu thế nổi bật đó, công ty mình từ lúc thành lập đã thành lập team Lab chuyên nghiên cứu và phát triển những dịch vụ về AI. Song hành với team Lab (chuyên về AI) là team Dev (chuyên về engineering) sẽ phát triển, tích hợp những dịch vụ liên quan để người dùng có thể trải nghiệm, sử dụng một cách thuận tiện.
Như các bạn đã biết, với những service về AI thường sẽ được phát triền bằng python vì vậy sẽ có những công cụ và sản phẩm để hỗ trợ và phát triển như fiftyone (hỗ trợ visualize datasets), những công cụ để annotate dữ liệu: CVAT, Label Studio,…
Cuộc sống đưa đẩy, anh lead team mình muốn mình tham gia vào dự án phát triển sản phẩm để hỗ trợ quy trình phát triền annotate dữ liệu và các service xung quanh. Lại một lần nữa mình gặp lại bạn ‘rắn’ Python, một bạn khá gọn gàng và thân thiện. Mình gặp ‘bạn ấy’ vào tiết học đầu tiên về lập trình ở trường đại học.
Để cập nhật những thay đổi về ‘tính cách’ của ‘bạn ấy’ trong suốt 6 năm xa cách, hôm nay mình quyết định học và note lại những thứ mình ấn tượng nhất trong tính cách thay đổi của bạn Python. Một tính năng mình khá bất ngờ ở phiên bản hiện tại (3.9) là xử lý bất đồng bộ (asynchronous), đây cũng là thứ mình khá thích ở bạn NodeJS. Hãy cùng mình cập tìm hiểu bạn Python nào!
Asyncio - một module quan trọng và hữu ích
Trong bản cập nhật python 3.4, module asyncio được giới thiệu giúp người dùng có thể dễ dàng viết code xử lý những tính toán một cách đồng thời (concurrent) bằng cú pháp async/await.
Từ việc giới thiệu module mới này, asyncio được dùng như là cơ sở để viết nên những frameworks bất đồng bộ hỗ trợ cho các ứng dụng web, thư viện kết nối database, …
Nó hỗ trợ những phương thức giao tiếp bậc cao (high-level API) như:
- Chạy những phương thức đồng thời và có toàn quyền kiểm soát việc thực thi nó.
- Làm những việc về networking(network IO and IPC)
- Phân chia những task qua những hàng đơi khác nhau
Một ví dụ demo nhỏ:
# example1-with-asyncio.py
import asyncio
async def count():
print("One")
await asyncio.sleep(1)
print("Two")
await asyncio.sleep(1)
print("Three")
async def main():
await asyncio.gather(count(), count(), count())
if __name__ == "__main__":
asyncio.run(main())
# example1-without-asyncio.py
import time
def count():
print("One")
time.sleep(1)
print("Two")
time.sleep(1)
print("Three")
def main():
for _ in range(3):
count()
if __name__ == "__main__":
main()
Sau khi chạy 2 file trên, ta có thể dễ dàng thấy được khi sử dụng module asyncio thời gian xử lý nhanh hơn gấp 3 lần vì ở đây mình chạy 3 hàm count()
cùng một lúc thay vì chạy tuần tự như ở file thứ hai.
Như vậy từ demo đơn giản trên, ta có thể thấy được lợi ích của việc sử dụng module asyncio và việc xử lý bất đồng bộ trong việc lập trình.
Các bạn có thể tìm hiểu thêm những khái niệm của xử lý bất đồng bộ qua những keyworks: Parallelism, Multiprocessing, Concurrency, Threading. Mình sẽ viết những series về chủ đề này sau.
Khi nào nên sử dụng module asyncio
Asyncio là một module mạnh mẽ trong Python cho phép bạn viết code bất đồng bộ, cho phép thực thi đồng thời và hiệu quả các tác vụ. Một số tình huống mà bạn nên cân nhắc sử dụng asyncio:
- Những phép toán liên quan đến I/O: Asyncio cực kì hữu dụng khi chương trình của bạn tốn thời gian lớn cho việc đợi hoàn thành input/output như: gửi request, xử lý files, tương tác với database.
- Lập trình hướng sự kiện: Asyncio phù hợp cho mô hình lập trình hướng sự kiện. Nó cho phép bạn định nghĩa những hàm xử lý sự kiện (events handlers) như những coroutines và tương tác với nhiều sự kiện bất đồng bộ khác nhau.
- Craw dữ liệu: Khi thực hiện craw dữ liệu, asyncio cho phép bạn lấy dữ liệu từ nhiều nguồn khác nhau một cách đồng thời. Với cách này có thể giúp bạn tăng tốc lấy và xử lý dữ liệu và tránh việc bottlenecks trong việc đợi kết quả của từng response.
- Điều phối để xử lý những task song song: Asyncio có cơ chế như là “những công việc cho tương lai” (tasks and futures) nó cho phép điều phối và đồng bộ các tác vụ song song. Bạn có thể viết code để chờ nhiều task hoàn thành cùng một lúc xong mới thực hiện task tiếp theo. Điều này cực kì hữu ích nếu những task đó là độc lập với nhau
Kết luận
Nhìn chung, asyncio hiệu quả nhất khi xử lý các hoạt động liên quan đến I/O, các tác vụ đồng thời và các kịch bản hướng sự kiện. Nó cho phép bạn viết code hiệu quả và đáp ứng bằng cách tận dụng sức mạnh của lập trình bất đồng bộ.
Sau 6 năm không gặp nhau, bây giờ bạn Python đã được nâng cấp và có những sức mạnh đáng ngưỡng mộ và có thể sánh ngang với các bạn ngôn ngữ lập trình khác.
Đây là bài viết đầu tiên trong series Learn with Bui, mong các bạn đóng góp thêm ý kiến để mình có thể cái thiện cho những bài viết tương lai. 🙇
All rights reserved