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 ProcessPoolExecutor trong Python
Trong bài viết này, bạn sẽ học cách sử dụng ProcessPoolExecutor
trong Python để tạo và quản lý một nhóm tiến trình một cách hiệu quả. ProcessPoolExecutor
là một phần của module concurrent.futures
và cung cấp một phương pháp mạnh mẽ để quản lý các tiến trình, giúp tối ưu hóa hiệu suất xử lý các tác vụ phức tạp. Việc sử dụng ProcessPoolExecutor
không chỉ giúp bạn tiết kiệm thời gian mà còn giảm thiểu công sức cần thiết để quản lý các tiến trình thủ công, mang lại sự linh hoạt và hiệu quả cho các ứng dụng đòi hỏi nhiều tài nguyên CPU.
Giới thiệu về ProcessPoolExecutor trong Python
Trong bài hướng dẫn trước, bạn đã học cách chạy mã song song bằng cách tạo tiến trình thủ công sử dụng lớp Process
từ module multiprocessing
. Tuy nhiên, việc tạo tiến trình thủ công không hiệu quả.
Để quản lý các tiến trình hiệu quả hơn, bạn có thể sử dụng một nhóm tiến trình (process pool). Giống như một nhóm luồng (thread pool), một nhóm tiến trình là một mẫu thiết kế để quản lý các tiến trình tự động.
Lớp ProcessPoolExecutor
từ module concurrent.futures
cho phép bạn tạo và quản lý một nhóm tiến trình.
Bài viết này được đăng tại [free tuts .net]
Ví dụ, lớp ProcessPoolExecutor
sử dụng số lượng lõi CPU để tạo ra số lượng tiến trình tối ưu.
Lớp ProcessPoolExecutor
mở rộng lớp Executor
có ba phương thức:
submit()
– phân phát một hàm để thực thi bởi tiến trình và trả về một đối tượng Future.map()
– gọi một hàm với một iterable của các phần tử.shutdown()
– tắt executor.
Để giải phóng tài nguyên do executor nắm giữ, bạn cần gọi phương thức shutdown()
một cách rõ ràng. Để tắt executor tự động, bạn có thể sử dụng một context manager.
Đối tượng Future đại diện cho kết quả của một hoạt động bất đồng bộ. Nó có hai phương thức chính để lấy kết quả:
result()
– trả về kết quả từ hoạt động bất đồng bộ.exception()
– trả về một ngoại lệ xảy ra trong khi chạy hoạt động bất đồng bộ.
Ví dụ về ProcessPoolExecutor trong Python
Chương trình sau sử dụng một nhóm tiến trình để tạo hình thu nhỏ cho các bức ảnh trong thư mục images
và lưu chúng vào thư mục thumbs
.
import time import os from PIL import Image, ImageFilter from concurrent.futures import ProcessPoolExecutor filenames = [ 'images/1.jpg', 'images/2.jpg', 'images/3.jpg', 'images/4.jpg', 'images/5.jpg', ] def create_thumbnail(filename, size=(50, 50), thumb_dir='thumbs'): # mở ảnh img = Image.open(filename) # áp dụng bộ lọc gaussian blur img = img.filter(ImageFilter.GaussianBlur()) # tạo hình thu nhỏ img.thumbnail(size) # lưu ảnh img.save(f'{thumb_dir}/{os.path.basename(filename)}') # hiển thị thông báo print(f'{filename} đã được xử lý...') def main(): start = time.perf_counter() with ProcessPoolExecutor() as executor: executor.map(create_thumbnail, filenames) finish = time.perf_counter() print(f'Mất {finish - start:.2f} giây để hoàn thành') if __name__ == '__main__': main()
Đầu ra:
images/5.jpg đã được xử lý... images/4.jpg đã được xử lý... images/3.jpg đã được xử lý... images/2.jpg đã được xử lý... images/1.jpg đã được xử lý... Mất 0.79 giây để hoàn thành
Chú ý: Để chạy chương trình, bạn cần cài đặt Pillow, một thư viện phổ biến cho xử lý ảnh, bằng cách chạy lệnh pip: pip install Pillow
.
Cách hoạt động:
Đầu tiên, khai báo danh sách các tệp cần tạo hình thu nhỏ:
filenames = [ 'images/1.jpg', 'images/2.jpg', 'images/3.jpg', 'images/4.jpg', 'images/5.jpg', ]
Thứ hai, định nghĩa hàm tạo hình thu nhỏ từ tệp ảnh và lưu kết quả vào thư mục thumbs
:
def create_thumbnail(filename, size=(50, 50), thumb_dir='thumbs'): # mở ảnh img = Image.open(filename) # áp dụng bộ lọc gaussian blur img = img.filter(ImageFilter.GaussianBlur()) # tạo hình thu nhỏ img.thumbnail(size) # lưu ảnh img.save(f'{thumb_dir}/{os.path.basename(filename)}') # hiển thị thông báo print(f'{filename} đã được xử lý...')
Thứ ba, tạo một nhóm tiến trình và gọi hàm create_thumbnail()
cho mỗi bức ảnh trong danh sách filenames
:
with ProcessPoolExecutor() as executor: executor.map(create_thumbnail, filenames)
Kết bài
Sử dụng lớp ProcessPoolExecutor
trong Python để tạo và quản lý một nhóm tiến trình tự động là một phương pháp hiệu quả để xử lý các tác vụ đòi hỏi nhiều tài nguyên CPU. Bằng cách tận dụng số lõi CPU có sẵn, ProcessPoolExecutor
giúp tối ưu hóa quá trình xử lý và tiết kiệm thời gian thực thi. Thay vì phải quản lý các tiến trình một cách thủ công, bạn có thể dễ dàng điều phối và theo dõi các tác vụ thông qua các phương pháp của ProcessPoolExecutor
, mang lại hiệu suất và sự linh hoạt cao hơn cho các ứng dụng của mình.