Khung dữ liệu trả về đa xử lý python

Trong bài này chúng ta sẽ tìm hiểu cách xử lý đa tiến trình trong Python. Đa xử lý hay còn gọi là đa xử lý, thường được sử dụng để xử lý nhiều tiến trình đang chạy song song

Bài viết này đã được đăng tại freetuts. net , không được sao chép dưới mọi hình thức.

Đa xử lý được tích hợp trong mô-đun đa xử lý, trong đó có lớp tiến trình, vì vậy bạn phải nhập thư viện này vào trước khi sử dụng nhé

1. Đa xử lý là gì?

Khả năng đa xử lý của một hệ thống hỗ trợ nhiều bộ vi xử lý bộ xử lý cùng một lúc. Các ứng dụng tương ứng trong hệ thống đa lý được chia thành nhiều quy trình nhỏ và chạy độc lập, và hệ điều hành sẽ phân bổ các luồng này cho bộ vi xử lý để cải thiện hiệu suất của hệ thống

Câu hỏi đặt ra là tại sao ta phải sử dụng đa xử lý?

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

Trong máy tính có một bộ xử lý duy nhất, nếu bộ xử lý chỉ được định chạy nhiều quy trình cùng lúc thì nó sẽ phải phân chia các tác vụ [tác vụ] bằng cách ngắt tác vụ này và chạy tác vụ kia một cách liên tục, điều này giúp chắc chắn

Điều này giống như người đầu bếp, khi khách hàng vào đặt nhiều món thì đầu bếp sẽ phải nấu nhiều món cùng lúc, phân chia thời gian giữa các món để đảm bảo món nào cũng được nấu đúng giờ.

Việc làm nhiều việc cùng lúc sẽ làm cho hiệu quả công việc không được tốt, sản phẩm hoàn thành không được như mong đời. Chính điều này đã xuất hiện thêm khái niệm xử lý đa tiến trình

2. Đa xử lý trong Python là gì?

Đa xử lý trong Python là một mô-đun hỗ trợ lập trình viên có thể phân chia công việc theo nhiều quy trình. Bằng cách thông qua các phương thức [API] mà mô-đun cung cấp sẵn, chúng ta có thể quản lý các tác vụ một cách dễ dàng

Để hiểu rõ về xử lý song song tiến trình, bạn phải biết có bao nhiêu lõi trong máy tính đang sử dụng, và mô-đun đa xử lý sẽ giúp bạn biết được điều đó, bằng cách sử dụng đoạn mã đơn giản dưới đây

import multiprocessing
print["Số lượng cpu : ", multiprocessing.cpu_count[]]

Kết quả trên máy tính của mình là

Số lượng cpu :  8

Đây chỉ là mới tham khảo số lượng CPU. Nếu bạn muốn tìm hiểu sâu hơn thì hãy tiếp tục với các ví dụ bên dưới nhé

Ví dụ 1. Bây giờ hãy xem đơn giản đoạn mã dưới đây

# importing module multiprocessing
import multiprocessing

def print_cube[num]:
    """
    Hàm in thể tích của khối lập phương
    """
    print["Giá trị lập phương: {}".format[num * num * num]]

def print_square[num]:
    """
    Hàm in diện tích hình vuông
    """
    print["Diện tích hình vuông: {}".format[num * num]]

# Chương trình chính
if __name__ == "__main__":
    # Tạo hai tiến trình process
    p1 = multiprocessing.Process[target=print_square, args=[10, ]]
    p2 = multiprocessing.Process[target=print_cube, args=[10, ]]

    # Bắt đầu process 1
    p1.start[]
    # Bắt đầu process 2
    p2.start[]

    # Chờ tới khi process 1 hoàn thành
    p1.join[]
    # Chờ tới khi process 2 hoàn thành
    p2.join[]

    # Cả hai processes hoàn thành
    print["Done!"]

Kết quả

Diện tích hình vuông: 100
Giá trị lập phương: 1000
Done!

Giải thích một chút về chương trình

  • Đoạn mã
    Số lượng cpu :  8
    0 dùng để khai báo sử dụng mô-đun đa xử lý
  • Để tạo một process, ta sử dụng tên class là Process, it has hai tham số như sau
    • Số lượng cpu :  8
      1 là hàm được gọi để chạy
    • Số lượng cpu :  8
      2 là các tham số sẽ truyền vào hàm đích
    • Lớp
      Số lượng cpu :  8
      3 cũng có thêm các tham số khác, nhưng chúng ta sẽ tìm hiểu nó sau nhé
  • To start a process, ta call to start method
  • To Stop tạm thời chương trình, tức là đợi hai tiến trình xử lý xong, ta sử dụng phương thức tham gia
  • Như vậy đoạn mã
    Số lượng cpu :  8
    4 chỉ được thực thi khi hai tiến trình phía trên hoàn tất

Nếu bạn vẫn chưa cấu hình được việc xử lý các tiến trình là riêng biệt, hãy tham khảo thêm ví dụ 2 dưới đây

Ví dụ 2. Kiểm tra ID tiến trình và trạng thái của tiến trình

# importing multiprocessing và os module
import multiprocessing
import os

def worker1[]:
    # In ra process id của worker1
    print["ID của tiến trình worker1: {}".format[os.getpid[]]]

def worker2[]:
    # In ra process id của worker2
    print["ID của tiến trình worker2: {}".format[os.getpid[]]]

# Chương trình chính
if __name__ == "__main__":
    # In ra process id của chương trình chính
    print["ID của chương trình chính: {}".format[os.getpid[]]]

    # Tạo processes
    p1 = multiprocessing.Process[target=worker1]
    p2 = multiprocessing.Process[target=worker2]

    # Chạy processes
    p1.start[]
    p2.start[]

    # Lấy process IDs
    print["ID của process p1: {}".format[p1.pid]]
    print["ID của process p2: {}".format[p2.pid]]

    # Chờ cho tới khi 2 process p1 và p2 hoàn thành
    p1.join[]
    p2.join[]

    # In thông báo cả hai đã hoàn thành
    print["Cả hai tiến trình đã hoàn thành!"]

    # Kiểm tra trạng thái của hai process
    print["Process p1 có đang chạy? {}".format[p1.is_alive[]]]
    print["Process p2 có đang chạy? {}".format[p2.is_alive[]]]

Kết quả

Số lượng cpu :  8
0

Giải thích một chút nhé

  • Phương thức is_alive[] dùng để kiểm tra một tiến trình đang hoạt động hay không
  • Thuộc tính pid lưu trữ ID của tiến trình
  • Đoạn mã
    Số lượng cpu :  8
    5 dùng để lấy pid của chương trình chính

Như bạn thấy, từ tiến trình chính mình đã phân chia thành hai tiến trình con p1 và p2, điều này tương tự như hình sau

Bạn cũng có thể hiểu đơn giản là "một công việc được chia cho hai công nhân"

3. Multiprocessing has not space memory

Trong Python, các process chạy độc lập và không có bộ nhớ riêng

Ví dụ, bạn sử dụng một biến toàn cầu ở hai tiến trình khác nhau thì việc thay giá trị cho biến đó ở hai tiến trình là không ảnh hưởng đến nhau

Xem ví dụ dưới đây để hiểu rõ hơn

Số lượng cpu :  8
2

Kết quả

Số lượng cpu :  8
3

Giải thích nhé

  • Biến
    Số lượng cpu :  8
    6 là một biến cục bộ [toàn cầu]
  • Trong
    Số lượng cpu :  8
    7 mình đã thêm một phần tử cho biến này, sau đó vào ra
  • Sau khi
    Số lượng cpu :  8
    7 xử lý xong thì in value result at main program
  • => Kết quả là các giá trị khác nhau hoàn toàn

Như vậy tất cả các tiến trình đều có thể sử dụng dữ liệu toàn cục, nhưng chúng sẽ có bộ nhớ xử lý khác nhau nên không ảnh hưởng lẫn nhau

4. Bộ nhớ dùng chung trong Xử lý Python

Như phần 3 mình đã trình bày, các bộ xử lý không có thời gian lưu trữ và chạy độc lập với nhau. Tuy nhiên, có những lúc ta muốn chia sẻ dữ liệu giữa chúng ta thì làm thế nào?

Ta sẽ sử dụng hai phương thức

  • Số lượng cpu :  8
    9 used to share data array. Nó sẽ tạo ra một SynchronizedArray chứ không phải mảng bình thường, vì vậy bạn không thể sử dụng các phương thức như
    # importing module multiprocessing
    import multiprocessing
    
    def print_cube[num]:
        """
        Hàm in thể tích của khối lập phương
        """
        print["Giá trị lập phương: {}".format[num * num * num]]
    
    def print_square[num]:
        """
        Hàm in diện tích hình vuông
        """
        print["Diện tích hình vuông: {}".format[num * num]]
    
    # Chương trình chính
    if __name__ == "__main__":
        # Tạo hai tiến trình process
        p1 = multiprocessing.Process[target=print_square, args=[10, ]]
        p2 = multiprocessing.Process[target=print_cube, args=[10, ]]
    
        # Bắt đầu process 1
        p1.start[]
        # Bắt đầu process 2
        p2.start[]
    
        # Chờ tới khi process 1 hoàn thành
        p1.join[]
        # Chờ tới khi process 2 hoàn thành
        p2.join[]
    
        # Cả hai processes hoàn thành
        print["Done!"]
    0,
  • # importing module multiprocessing
    import multiprocessing
    
    def print_cube[num]:
        """
        Hàm in thể tích của khối lập phương
        """
        print["Giá trị lập phương: {}".format[num * num * num]]
    
    def print_square[num]:
        """
        Hàm in diện tích hình vuông
        """
        print["Diện tích hình vuông: {}".format[num * num]]
    
    # Chương trình chính
    if __name__ == "__main__":
        # Tạo hai tiến trình process
        p1 = multiprocessing.Process[target=print_square, args=[10, ]]
        p2 = multiprocessing.Process[target=print_cube, args=[10, ]]
    
        # Bắt đầu process 1
        p1.start[]
        # Bắt đầu process 2
        p2.start[]
    
        # Chờ tới khi process 1 hoàn thành
        p1.join[]
        # Chờ tới khi process 2 hoàn thành
        p2.join[]
    
        # Cả hai processes hoàn thành
        print["Done!"]
    1 used for shared data menu. Nó sẽ trả về một Đồng bộ hóa, vì vậy bạn muốn lấy hay gán giá trị thì phải thông qua thuộc tính
    # importing module multiprocessing
    import multiprocessing
    
    def print_cube[num]:
        """
        Hàm in thể tích của khối lập phương
        """
        print["Giá trị lập phương: {}".format[num * num * num]]
    
    def print_square[num]:
        """
        Hàm in diện tích hình vuông
        """
        print["Diện tích hình vuông: {}".format[num * num]]
    
    # Chương trình chính
    if __name__ == "__main__":
        # Tạo hai tiến trình process
        p1 = multiprocessing.Process[target=print_square, args=[10, ]]
        p2 = multiprocessing.Process[target=print_cube, args=[10, ]]
    
        # Bắt đầu process 1
        p1.start[]
        # Bắt đầu process 2
        p2.start[]
    
        # Chờ tới khi process 1 hoàn thành
        p1.join[]
        # Chờ tới khi process 2 hoàn thành
        p2.join[]
    
        # Cả hai processes hoàn thành
        print["Done!"]
    2

# importing module multiprocessing
import multiprocessing

def print_cube[num]:
    """
    Hàm in thể tích của khối lập phương
    """
    print["Giá trị lập phương: {}".format[num * num * num]]

def print_square[num]:
    """
    Hàm in diện tích hình vuông
    """
    print["Diện tích hình vuông: {}".format[num * num]]

# Chương trình chính
if __name__ == "__main__":
    # Tạo hai tiến trình process
    p1 = multiprocessing.Process[target=print_square, args=[10, ]]
    p2 = multiprocessing.Process[target=print_cube, args=[10, ]]

    # Bắt đầu process 1
    p1.start[]
    # Bắt đầu process 2
    p2.start[]

    # Chờ tới khi process 1 hoàn thành
    p1.join[]
    # Chờ tới khi process 2 hoàn thành
    p2.join[]

    # Cả hai processes hoàn thành
    print["Done!"]
1

Kết quả

# importing module multiprocessing
import multiprocessing

def print_cube[num]:
    """
    Hàm in thể tích của khối lập phương
    """
    print["Giá trị lập phương: {}".format[num * num * num]]

def print_square[num]:
    """
    Hàm in diện tích hình vuông
    """
    print["Diện tích hình vuông: {}".format[num * num]]

# Chương trình chính
if __name__ == "__main__":
    # Tạo hai tiến trình process
    p1 = multiprocessing.Process[target=print_square, args=[10, ]]
    p2 = multiprocessing.Process[target=print_cube, args=[10, ]]

    # Bắt đầu process 1
    p1.start[]
    # Bắt đầu process 2
    p2.start[]

    # Chờ tới khi process 1 hoàn thành
    p1.join[]
    # Chờ tới khi process 2 hoàn thành
    p2.join[]

    # Cả hai processes hoàn thành
    print["Done!"]
2

Bên trong tiến trình process1 mình đã thay đổi giá trị cho Array và Value của các đối tượng, và nó được lưu lại cho mọi tiến trình chạy sau nó

Lời kết. Trên là tổng hợp một số kiến ​​thức quan trọng về xử lý đa tiến trình đa xử lý trong Python. Đây là một kiến ​​thức nâng cao khá hay, và mình nghĩ các bạn nên dành chút thời gian để thực hiện theo sẽ giúp ích rất nhiều trong việc hiểu biết về đa tiến trình

Chủ Đề