Python Async Programming: Thành Thạo asyncio

Python Async Programming: Thành Thạo asyncio
Lập trình bất đồng bộ là một trong những kỹ thuật mạnh mẽ nhất để xây dựng ứng dụng Python hiệu suất cao. Với asyncio và cú pháp async/await, bạn có thể xử lý hàng ngàn operations đồng thời một cách hiệu quả—thiết yếu cho web servers, API clients, và các ứng dụng I/O-bound. Hướng dẫn này đưa bạn từ fundamentals đến production-ready patterns.
Những Gì Bạn Sẽ Học
✅ Cú pháp async/await cơ bản
✅ Event loops và cách chúng hoạt động
✅ Coroutines và Tasks
✅ Concurrent operations với asyncio.gather
✅ Async context managers và iterators
✅ Error handling trong async code
✅ Best practices cho async programming
✅ Khi nào dùng async vs threading vs multiprocessing
Điều Kiện Tiên Quyết
Trước khi tìm hiểu async programming, bạn nên hiểu:
- Python functions và basics từ Giai Đoạn 1: Nền Tảng
- Decorators từ Python Decorators Deep Dive
Ghi chú: Phần này chứa các ví dụ code tương tự phiên bản tiếng Anh. Để tiết kiệm không gian, chúng tôi tập trung vào giải thích khái niệm bằng tiếng Việt và giữ nguyên code examples.
1. Hiểu Lập Trình Bất Đồng Bộ
Vấn đề: Synchronous code blocks khi chờ I/O operations. Ví dụ: 3 network requests tuần tự mất 6 giây (2s × 3).
Giải pháp: Async programming cho phép start nhiều operations và handle chúng khi complete. Với asyncio.gather(), 3 requests chạy đồng thời chỉ mất ~2 giây (thời gian của operation lâu nhất).
Key Insight: Async không làm individual operations nhanh hơn—nó cho phép làm nhiều operations hơn trong cùng thời gian bằng cách không block khi waiting.
2. Core Concepts
Coroutines: Function định nghĩa với async def. Khi gọi, nó returns coroutine object, không phải result. Phải await hoặc dùng asyncio.run() để get result.
await keyword: Pauses coroutine cho đến khi awaited operation completes. Chỉ dùng được trong async def function.
Event Loop: Core của asyncio - manages tất cả running coroutines, schedules khi chúng run, handles I/O events efficiently. Dùng asyncio.run() để manage event loop (Python 3.10+ best practice).
3. Tasks và Concurrent Execution
Creating Tasks: asyncio.create_task() wraps coroutine và schedules nó run trên event loop. Tasks start immediately khi created.
asyncio.gather(): Runs nhiều coroutines concurrently, returns results theo thứ tự. Perfect cho fetching multiple resources.
asyncio.wait(): More control - cho phép handle completed tasks individually, set return_when conditions.
asyncio.as_completed(): Process results as they arrive (fastest first). Useful khi cần handle results ngay khi ready.
4. Async Context Managers và Iterators
Async Context Managers: Dùng async with cho resources cần async setup/cleanup. Implement __aenter__ và __aexit__ methods. Hoặc dùng @asynccontextmanager decorator từ contextlib.
Async Iterators: Dùng async for để iterate over async data streams. Implement __aiter__ và __anext__ methods. Raise StopAsyncIteration khi done.
Async Generators (Python 3.6+): Dùng async def với yield để create async generators. Useful cho streaming data.
5. Error Handling trong Async Code
Basic try/except: Works bình thường với await. Wrap async calls trong try/except blocks.
gather() với return_exceptions=True: Exceptions được return as results thay vì raised. Allows processing partial results khi some tasks fail.
Task Cancellation: Catch asyncio.CancelledError để cleanup resources. Always re-raise sau khi cleanup.
Timeouts: asyncio.timeout(seconds) (Python 3.11+) hoặc asyncio.wait_for(coro, timeout) cho older versions. Raises TimeoutError khi exceeded.
6. Synchronization Primitives
asyncio.Lock: Prevent race conditions khi multiple coroutines access shared resources. Dùng async with lock:.
asyncio.Semaphore: Limit number of concurrent operations. Ví dụ: Semaphore(3) cho phép max 3 concurrent API calls.
asyncio.Event: Coordinate coroutines với signals. event.set() signals tất cả waiters, await event.wait() blocks until set.
asyncio.Queue: Producer-consumer pattern. await queue.put(item), await queue.get(), queue.task_done(), await queue.join().
7. Real-World Example: Async HTTP Client
Dùng aiohttp library cho async HTTP requests:
- Create
ClientSessionvớiasync with - Fetch JSON với
session.get()vàawait response.json() - Rate limiting với Semaphore + delay
Rate-Limited API Client pattern: Combine Semaphore để limit concurrent requests và delay sau mỗi request để respect rate limits.
8. Async vs Threading vs Multiprocessing
| Approach | Best For | GIL Affected | Overhead |
|---|---|---|---|
| asyncio | I/O-bound (network, files) | Yes, nhưng không matter | Low |
| threading | I/O-bound, C extensions | Yes | Medium |
| multiprocessing | CPU-bound (calculations) | No (separate processes) | High |
Running Blocking Code trong Async: Dùng loop.run_in_executor() với ThreadPoolExecutor (I/O) hoặc ProcessPoolExecutor (CPU).
9. Best Practices
✅ Do's:
- Dùng
asyncio.run()cho entry point - Dùng async context managers cho resources
- Dùng
gather()cho concurrent operations - Handle exceptions properly với try/except
- Dùng timeouts cho network operations
- Dùng semaphores cho rate limiting
❌ Don'ts:
- Không dùng
time.sleep()trong async code - dùngasyncio.sleep() - Không forget await coroutines
- Không create event loops manually
- Không mix sync và async không có executor
10. Common Pitfalls
Pitfall 1: Forgetting to await - Coroutine returns coroutine object, không run. Always await!
Pitfall 2: Blocking the Event Loop - Dùng requests library blocks tất cả coroutines. Dùng aiohttp instead.
Pitfall 3: Creating Tasks Without Awaiting - Task might not complete trước khi program ends. Keep reference và await.
Pitfall 4: Not Handling Cancellation - Resources may leak. Dùng try/finally hoặc catch CancelledError để cleanup.
Summary
Trong guide này, bạn đã học:
✅ Async fundamentals: coroutines, await, event loop
✅ Creating và managing Tasks
✅ Concurrent execution với gather(), wait(), as_completed()
✅ Async context managers và iterators
✅ Error handling và timeouts
✅ Synchronization primitives (Lock, Semaphore, Event, Queue)
✅ Khi nào dùng async vs threading vs multiprocessing
✅ Best practices và common pitfalls
Async programming là thiết yếu cho building high-performance Python applications, đặc biệt web servers và API clients. Với FastAPI, async là default và enables handling hàng ngàn concurrent requests efficiently.
Bước Tiếp Theo
Giờ bạn đã hiểu async programming, khám phá các chủ đề liên quan:
Thêm Python Deep Dives:
- Python Testing với pytest - Test async code
- Package Management với Poetry - Modern project setup
Áp Dụng Async trong Web Development:
- FastAPI Learning Roadmap - FastAPI dùng async natively
Quay Lại Roadmap:
- Python Learning Roadmap - Lộ trình học hoàn chỉnh
- Giai Đoạn 3: Standard Library & Tools - Nơi async được giới thiệu
Thuộc chuỗi bài Lộ Trình Học Python
📬 Đăng ký nhận bản tin
Nhận những bài viết mới nhất qua email mỗi tuần. Không spam, hủy đăng ký bất cứ lúc nào.
Chúng tôi tôn trọng quyền riêng tư của bạn. Hủy đăng ký bất cứ lúc nào.
💬 Comments
Đăng nhập để bình luận
Chúng tôi sẽ không đăng bất cứ điều gì mà không có sự cho phép của bạn.