PYTHON CONCURRENCY
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

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.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

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.

Cùng chuyên mục:

Hướng dẫn xây dựng Command-Line Interface (CLI) bằng Quo trong Python

Hướng dẫn xây dựng Command-Line Interface (CLI) bằng Quo trong Python

Hướng dẫn toàn diện về module datetime trong Python

Hướng dẫn toàn diện về module datetime trong Python

Cách truy cập và thiết lập biến môi trường trong Python

Cách truy cập và thiết lập biến môi trường trong Python

Lớp dữ liệu (Data Classes) trong Python với decorator @dataclass

Lớp dữ liệu (Data Classes) trong Python với decorator @dataclass

Từ khóa yield trong Python

Từ khóa yield trong Python

Sự khác biệt giữa sort() và sorted() trong Python

Sự khác biệt giữa sort() và sorted() trong Python

Sử dụng Poetry để quản lý dependencies trong Python

Sử dụng Poetry để quản lý dependencies trong Python

Định dạng chuỗi Strings trong Python

Định dạng chuỗi Strings trong Python

Một tác vụ phổ biến khi làm việc với danh sách trong Python

Một tác vụ phổ biến khi làm việc với danh sách trong Python

Làm việc với các biến môi trường trong Python

Làm việc với các biến môi trường trong Python

Sự khác biệt giữa set() và frozenset() trong Python

Sự khác biệt giữa set() và frozenset() trong Python

Sự khác biệt giữa iterator và iterable trong Python

Sự khác biệt giữa iterator và iterable trong Python

Cách làm việc với file tarball/tar trong Python

Cách làm việc với file tarball/tar trong Python

Chuyển đổi kiểu dữ liệu trong Python

Chuyển đổi kiểu dữ liệu trong Python

Sự khác biệt giữa toán tử == và is trong Python

Sự khác biệt giữa toán tử == và is trong Python

Làm việc với file ZIP trong Python

Làm việc với file ZIP trong Python

Cách sử dụng ThreadPoolExecutor trong Python

Cách sử dụng ThreadPoolExecutor trong Python

Sự khác biệt giữa byte objects và string trong Python

Sự khác biệt giữa byte objects và string trong Python

Xử lý độ chính xác các hàm floor, ceil, round, trunc, format  trong Python

Xử lý độ chính xác các hàm floor, ceil, round, trunc, format trong Python

Cách lặp qua nhiều list với hàm zip() trong Python

Cách lặp qua nhiều list với hàm zip() trong Python

Top