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.

Sử dụng đa xử lý trong Python

Trong bài viết này, bạn sẽ học cách sử dụng module multiprocessing trong Python để chạy mã đồng thời. Multiprocessing là một kỹ thuật mạnh mẽ cho phép tận dụng tối đa tài nguyên của CPU bằng cách thực hiện nhiều tác vụ đồng thời, giúp tăng hiệu suất và giảm thời gian xử lý cho các ứng dụng đòi hỏi tài nguyên cao. Hãy cùng tìm hiểu cách triển khai và sử dụng multiprocessing để xử lý các tác vụ nặng một cách hiệu quả trong Python.

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ề đa xử lý trong Python

Thông thường, chương trình xử lý hai loại tác vụ chính:

  • Tác vụ I/O-bound: Nếu một tác vụ thực hiện nhiều thao tác nhập/xuất, nó được gọi là tác vụ I/O-bound. Ví dụ điển hình của tác vụ I/O-bound là đọc từ tệp, ghi vào tệp, kết nối cơ sở dữ liệu và thực hiện yêu cầu mạng. Đối với tác vụ I/O-bound, bạn có thể sử dụng đa luồng (multithreading) để tăng tốc.
  • Tác vụ CPU-bound: Khi một tác vụ thực hiện nhiều thao tác sử dụng CPU, nó được gọi là tác vụ CPU-bound. Ví dụ như tính toán số học, thay đổi kích thước ảnh và phát trực tuyến video là các tác vụ CPU-bound. Để tăng tốc chương trình với nhiều tác vụ CPU-bound, bạn sử dụng đa xử lý (multiprocessing).

Đa xử lý cho phép hai hoặc nhiều bộ xử lý xử lý đồng thời hai hoặc nhiều phần khác nhau của một chương trình.

Trong Python, bạn sử dụng module multiprocessing để thực hiện đa xử lý.

Bài viết này được đăng tại [free tuts .net]

Ví dụ về đa xử lý trong Python

Xem chương trình sau:

import time

def task():
    result = 0
    for _ in range(10**8):
        result += 1
    return result

if __name__ == '__main__':
    start = time.perf_counter()
    task()
    task()
    finish = time.perf_counter()

    print(f'It took {finish-start:.2f} second(s) to finish')

Kết quả:

It took 5.55 second(s) to finish

Giải thích cách hoạt động:

Đầu tiên, định nghĩa hàm task() là một tác vụ CPU-bound vì nó thực hiện một phép tính nặng bằng cách lặp lại 100 triệu lần và tăng một biến result:

def task():
    result = 0
    for _ in range(10**8):
        result += 1
    return result

Thứ hai, gọi hàm task() hai lần và ghi lại thời gian xử lý:

if __name__ == '__main__':
    start = time.perf_counter()
    task()
    task()
    finish = time.perf_counter()

    print(f'It took {finish-start: .2f} second(s) to finish')

Trên máy tính của chúng tôi, mất 5.55 giây để hoàn thành.

Sử dụng module multiprocessing trong Python

Chương trình sau sử dụng module multiprocessing nhưng mất ít thời gian hơn:

import time
import multiprocessing

def task() -> int:
    result = 0
    for _ in range(10**8):
        result += 1
    return result

if __name__ == '__main__':
    start = time.perf_counter()

    p1 = multiprocessing.Process(target=task)
    p2 = multiprocessing.Process(target=task)

    p1.start()
    p2.start()

    p1.join()
    p2.join()

    finish = time.perf_counter()
    print(f'It took {finish-start:.2f} second(s) to finish')

Kết quả:

It took 3.43 second(s) to finish

Giải thích cách hoạt động:

Đầu tiên, nhập module multiprocessing:

import multiprocessing

Thứ hai, tạo hai tiến trình và truyền hàm task vào mỗi tiến trình:

p1 = multiprocessing.Process(target=task)
p2 = multiprocessing.Process(target=task)

Lưu ý rằng hàm khởi tạo Process() trả về một đối tượng Process mới.

Thứ ba, gọi phương thức start() của các đối tượng Process để bắt đầu tiến trình:

p1.start()
p2.start()

Cuối cùng, chờ tiến trình hoàn thành bằng cách gọi phương thức join():

Ví dụ thực tế về đa xử lý trong Python

Chúng ta sẽ sử dụng module multiprocessing để thay đổi kích thước các ảnh có độ phân giải cao.

Đầu tiên, cài đặt thư viện Pillow để xử lý ảnh:

pip install Pillow

Thứ hai, phát triển một chương trình tạo thumbnail của cá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

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 thumbnail
    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ý...')


if __name__ == '__main__':
    start = time.perf_counter()

    for filename in filenames:
        create_thumbnail(filename)
        
    finish = time.perf_counter()

    print(f'Mất {finish-start:.2f} giây để hoàn thành')

Trên máy tính của chúng tôi, mất khoảng 4.06 giây để hoàn thành:

images/1.jpg đã được xử lý...
images/2.jpg đã được xử lý...
images/3.jpg đã được xử lý...
images/4.jpg đã được xử lý...
images/5.jpg đã được xử lý...
Mất 4.06 giây để hoàn thành

Thứ ba, sửa đổi chương trình để sử dụng đa xử lý. Mỗi tiến trình sẽ tạo một thumbnail cho một ảnh:

import time
import os
from PIL import Image, ImageFilter

import multiprocessing

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 thumbnail
    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()

    # tạo các tiến trình
    processes = [multiprocessing.Process(target=create_thumbnail, args=[filename]) 
                for filename in filenames]

    # bắt đầu các tiến trình
    for process in processes:
        process.start()

    # chờ hoàn thành
    for process in processes:
        process.join()

    finish = time.perf_counter()

    print(f'Mất {finish-start:.2f} giây để hoàn thành')


if __name__ == '__main__':
    main()

Kết quả:

images/5.jpg đã được xử lý...
images/4.jpg đã được xử lý...
images/1.jpg đã được xử lý...
images/3.jpg đã được xử lý...
images/2.jpg đã được xử lý...
Mất 2.92 giây để hoàn thành

Trong trường hợp này, kết quả cho thấy chương trình đã xử lý các ảnh nhanh hơn.

Kết bài

Sử dụng module multiprocessing trong Python để chạy mã đồng thời giúp xử lý các tác vụ CPU-bound một cách hiệu quả, tận dụng tối đa khả năng của CPU và giảm đáng kể thời gian xử lý. Bằng cách chia nhỏ các tác vụ lớn thành các quy trình nhỏ hơn và chạy chúng song song, bạn có thể cải thiện hiệu suất của ứng dụng và đạt được kết quả nhanh chóng hơn. Hãy áp dụng multiprocessing trong các dự án của bạn để khai thác tối đa tiềm năng của hệ thống và tối ưu hóa quá trình xử lý các tác vụ nặng.

Cùng chuyên mục:

Cách tạo một widget nhập ngày và giờ sử dụng PyQt QDateTimeEdit

Cách tạo một widget nhập ngày và giờ sử dụng PyQt QDateTimeEdit

Cách tạo một widget nhập giờ sử dụng lớp PyQt QTimeEdit

Cách tạo một widget nhập giờ sử dụng lớp PyQt QTimeEdit

Cách tạo một widget nhập ngày sử dụng lớp PyQt QDateEdit

Cách tạo một widget nhập ngày sử dụng lớp PyQt QDateEdit

Cách sử dụng widget PyQt QSpinBox để tạo một spin box

Cách sử dụng widget PyQt QSpinBox để tạo một spin box

Sử dụng PyQt QComboBox để tạo Widget Combobox

Sử dụng PyQt QComboBox để tạo Widget Combobox

Cách sử dụng lớp PyQt QRadioButton

Cách sử dụng lớp PyQt QRadioButton

Cách sử dụng lớp QCheckBox trong PyQt

Cách sử dụng lớp QCheckBox trong PyQt

Cách sử dụng QFormLayout trong PyQt

Cách sử dụng QFormLayout trong PyQt

Cách sử dụng QGridLayout trong PyQt

Cách sử dụng QGridLayout trong PyQt

Cách sử dụng QVBoxLayout trong PyQt

Cách sử dụng QVBoxLayout trong PyQt

Cách sử dụng widget QLineEdit trong PyQt

Cách sử dụng widget QLineEdit trong PyQt

Cách sử dụng widget QPushButton của PyQt

Cách sử dụng widget QPushButton của PyQt

Cách sử dụng widget PyQt QLabel

Cách sử dụng widget PyQt QLabel

Tín hiệu và Khe (Signals & Slots) trong PyQt

Tín hiệu và Khe (Signals & Slots) trong PyQt

PyQt là gì? Tạo một chương trình

PyQt là gì? Tạo một chương trình "Hello World".

Ứng dụng System Tray với Tkinter

Ứng dụng System Tray với Tkinter

Cách hiển thị đồ thị từ thư viện Matplotlib trong Tkinter

Cách hiển thị đồ thị từ thư viện Matplotlib trong Tkinter

Cách sử dụng Validate trong Tkinter

Cách sử dụng Validate trong Tkinter

Cấu trúc MVC trong Tkinter

Cấu trúc MVC trong Tkinter

Cách sử dụng widget PhotoImage của Tkinter

Cách sử dụng widget PhotoImage của Tkinter

Top