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 ThreadPoolExecutor trong Python
Nếu một chương trình Python chứa nhiều tác vụ I/O, chạy nó theo cách tuần tự/synchronous có thể làm tăng thời gian thực thi. Với thư viện đa luồng, thời gian này có thể giảm đáng kể. Bài viết này sẽ hướng dẫn cách sử dụng ThreadPoolExecutor của Python để thực hiện các hàm bằng các luồng.
Về ThreadPoolExecutor của Python
Một chương trình Python thông thường chạy với một tiến trình và một luồng duy nhất. Tuy nhiên, việc sử dụng nhiều luồng có thể cải thiện hiệu suất đáng kể.
ThreadPoolExecutor từ module concurrent.futures
giúp quản lý luồng một cách đơn giản qua API tiện lợi, tự động tạo và phân phối tác vụ cho các luồng. Điều này rất hữu ích cho các tác vụ I/O như web scraping, nơi một luồng có thể chờ phản hồi từ máy chủ trong khi các luồng khác tiếp tục thu thập dữ liệu.
Gán nhiều tác vụ bằng map() của Python
from concurrent.futures import ThreadPoolExecutor urls = ["python-engineer.com", "twitter.com", "youtube.com"] def scrape_site(url): res = f'{url} đã được thu thập!' return res pool = ThreadPoolExecutor(max_workers=8) results = pool.map(scrape_site, urls) # không chặn for res in results: print(res) # in kết quả khi có sẵn pool.shutdown()
Giải thích: Đầu tiên, tạo một instance của ThreadPoolExecutor
với số luồng công nhân (max_workers
). Phương thức map()
dùng để gán các tác vụ cho các luồng, trả về ngay lập tức một iterable cho phép truy xuất kết quả. Cuối cùng, gọi shutdown()
để giải phóng tài nguyên khi các tác vụ đã hoàn tất.
Bài viết này được đăng tại [free tuts .net]
Kết quả:
python-engineer.com đã được thu thập! twitter.com đã được thu thập! youtube.com đã được thu thập!
Gán một tác vụ duy nhất bằng submit()
from concurrent.futures import ThreadPoolExecutor pool = ThreadPoolExecutor(max_workers=8) future = pool.submit(my_task, argument) # không chặn value = future.result() # chặn print(value) pool.shutdown()
Phương thức submit()
gán một tác vụ vào thread pool và trả về một đối tượng Future
. Dùng result()
để truy cập kết quả (chặn cho đến khi có kết quả).
Sử dụng ThreadPoolExecutor với Context Manager của Python
Cách tốt nhất để sử dụng ThreadPoolExecutor
là với Context Manager, tự động gọi shutdown()
khi hoàn thành.
with ThreadPoolExecutor(max_workers=1) as pool: future = pool.submit(pow, 2, 15) print(future.result())
Trên đây là hướng dẫn cơ bản về cách sử dụng ThreadPoolExecutor
để tối ưu hóa hiệu suất chương trình Python trong các tác vụ I/O.
Kết bài
Qua bài viết, bạn đã nắm được cách sử dụng ThreadPoolExecutor
trong Python để tối ưu hóa hiệu suất cho các tác vụ I/O nặng, giảm thời gian thực thi và tối ưu hóa mã nguồn. Sử dụng map()
cho nhiều tác vụ và submit()
cho từng tác vụ riêng lẻ sẽ giúp quản lý luồng hiệu quả hơn. Việc áp dụng Context Manager cũng giúp đảm bảo tài nguyên được giải phóng tự động sau khi hoàn tất các tác vụ. Đây là một kỹ thuật quan trọng, giúp mã Python trở nên gọn gàng và hiệu quả hơn khi xử lý các tác vụ đa luồng.