Hướng dẫn python static variable multiprocessing - xử lý đa biến tĩnh python

Tôi đang cố gắng giữ một hàng đợi đa xử lý được xác định "tĩnh" thông qua nhiều quy trình, nhưng có vẻ như bối cảnh này không được sao chép vào quy trình sinh sản mới. Có cách nào để giữ chúng mà không cần lưu trữ chúng vào các lớp quy trình có nguồn gốc (vì vậy không có bản thân.Q = A.Q) không?

main.py

from class_b import B

if __name__ == "__main__":
    b = B()
    b.start()

    while True:
        pass

class_a.py

from multiprocessing import Process, Queue

class A(Process):
    q = Queue()

    def __init__(self) -> None:
        super().__init__(daemon=True)

class_b.py

from multiprocessing import Process
from class_a import A

class B(Process):

    def __init__(self):
        super().__init__(daemon=True)
        print(A.q)

    def run(self):
        print(A.q)

Bảng điều khiển



Hỏi ngày 14 tháng 12 năm 2020 lúc 13:57Dec 14, 2020 at 13:57

Hướng dẫn python static variable multiprocessing - xử lý đa biến tĩnh python

UscheuscheUsche

1733 Huy hiệu bạc11 Huy hiệu đồng3 silver badges11 bronze badges

2

Khi bạn nhập từ

from multiprocessing import Process, Queue

class A(Process):
    q = Queue()

    def __init__(self) -> None:
        super().__init__(daemon=True)
5 để truy cập
from multiprocessing import Process, Queue

class A(Process):
    q = Queue()

    def __init__(self) -> None:
        super().__init__(daemon=True)
6, thì
from multiprocessing import Process, Queue

class A(Process):
    q = Queue()

    def __init__(self) -> None:
        super().__init__(daemon=True)
7 cũng vậy trong quá trình riêng của nó. Sau đó sẽ có hai bản sao. Bạn nên tạo nó như một địa phương trong
from multiprocessing import Process, Queue

class A(Process):
    q = Queue()

    def __init__(self) -> None:
        super().__init__(daemon=True)
8 và chuyển nó vào
from multiprocessing import Process, Queue

class A(Process):
    q = Queue()

    def __init__(self) -> None:
        super().__init__(daemon=True)
9.

from class_b import B
from multiprocessing import Queue

if __name__ == "__main__":
    q = Queue()
    b = B(q)
    b.start()

    while True:
        pass

Sau đó làm cho

from multiprocessing import Process, Queue

class A(Process):
    q = Queue()

    def __init__(self) -> None:
        super().__init__(daemon=True)
9 lưu trữ tài liệu tham khảo đó cho chính nó:

from multiprocessing import Process

class B(Process):

    def __init__(self, q):
        super().__init__(daemon=True)
        print(q)
        self.q = q

    def run(self):
        print(self.q)

Đã trả lời ngày 14 tháng 12 năm 2020 lúc 14:06Dec 14, 2020 at 14:06

Quamranaquaranaquamrana

35.6K12 Huy hiệu vàng55 Huy hiệu bạc68 Huy hiệu đồng12 gold badges55 silver badges68 bronze badges

4

Thuộc tính pid lưu trữ ID của tiến trình.multiprocessing, thường được dùng để xử lý nhiều tiến trình chạy song song.

Đoạn code

from multiprocessing import Process
from class_a import A

class B(Process):

    def __init__(self):
        super().__init__(daemon=True)
        print(A.q)

    def run(self):
        print(A.q)
6 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 có không gian bộ nhớ riêng
  • Trong Python, các tiến trình chạy độc lập và có không gian bộ nhớ riêng.

Ví dụ, bạn sử dụng một biến global ở 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.freetuts.net, không được copy dưới mọi hình thức.

Xem ví dụ dưới đây để hiểu rõ hơn.multiprocessing, trong đó có lớp process, vì vậy bạn phải import thư viện này vào trước khi sử dụng 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 có không gian bộ nhớ riêngtại sao ta phải sư dụng multiprocessing? Hãy đặt một ví dụ về máy tính có một processor nhé.

Trong Python, các tiến trình chạy độc lập và có không gian bộ nhớ riêng.

Ví dụ, bạn sử dụng một biến global ở 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.

Giải thích nhé:

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 có không gian bộ nhớ riêng

Để hiểu rõ về xử lý tiến trình song song thì bạn phải biết có bao nhiêu core trong máy tính đang sử dụng, và module multiprocessing 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.multiprocessing 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à:

Đấ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ụ phía dưới nhé.

Ví dụ 1: Bây giờ hãy xem một đoạn code đơn giản dưới đây.: Bây giờ hãy xem một đoạn code đơn giản 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 code
    from multiprocessing import Process
    from class_a import A
    
    class B(Process):
    
        def __init__(self):
            super().__init__(daemon=True)
            print(A.q)
    
        def run(self):
            print(A.q)
    
    1 dùng để khai báo sử dụng module multiprocessing.
  • Để tạo một process thì ta sử dụng class tên là Process, nó có hai tham số như sau: Process, nó có hai tham số như sau:
    • from multiprocessing import Process
      from class_a import A
      
      class B(Process):
      
          def __init__(self):
              super().__init__(daemon=True)
              print(A.q)
      
          def run(self):
              print(A.q)
      
      2 là hàm được gọi để chạy
    • from multiprocessing import Process
      from class_a import A
      
      class B(Process):
      
          def __init__(self):
              super().__init__(daemon=True)
              print(A.q)
      
          def run(self):
              print(A.q)
      
      3 là các tham số sẽ truyền vào hàm target
    • Class
      from multiprocessing import Process
      from class_a import A
      
      class B(Process):
      
          def __init__(self):
              super().__init__(daemon=True)
              print(A.q)
      
          def run(self):
              print(A.q)
      
      4 cũng có thêm các tham số khác, nhưng chúng ta sẽ tìm hiểu nó sau nhé.
  • Để bắt đầu một tiến trình thì ta gọi đến phương thức start.start.
  • Để dừng chương trình tạm thời, tức là chờ hai tiến trình xử lý xong thì ta sử dụng phương thức join.join.
  • Như vậy đoạn code
    from multiprocessing import Process
    from class_a import A
    
    class B(Process):
    
        def __init__(self):
            super().__init__(daemon=True)
            print(A.q)
    
        def run(self):
            print(A.q)
    
    5 chỉ được thực chạy khi hai tiến trình phía trên hoàn thành.

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

Ví dụ 2: Kiểm tra process ID và trạng thái của process.: Kiểm tra process ID và trạng thái của process.

# 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ả::

from multiprocessing import Process, Queue

class A(Process):
    q = Queue()

    def __init__(self) -> None:
        super().__init__(daemon=True)
0

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

  • Đoạn code
    from multiprocessing import Process
    from class_a import A
    
    class B(Process):
    
        def __init__(self):
            super().__init__(daemon=True)
            print(A.q)
    
        def run(self):
            print(A.q)
    
    1 dùng để khai báo sử dụng module multiprocessing.is_alive() dùng để kiểm tra một tiến trình đang live hay không.
  • Để tạo một process thì ta sử dụng class tên là Process, nó có hai tham số như sau: pid lưu trữ ID của tiến trình.
  • from multiprocessing import Process
    from class_a import A
    
    class B(Process):
    
        def __init__(self):
            super().__init__(daemon=True)
            print(A.q)
    
        def run(self):
            print(A.q)
    
    2 là hàm được gọi để chạy

from multiprocessing import Process
from class_a import A

class B(Process):

    def __init__(self):
        super().__init__(daemon=True)
        print(A.q)

    def run(self):
        print(A.q)
3 là các tham số sẽ truyền vào hàm target

Class

from multiprocessing import Process
from class_a import A

class B(Process):

    def __init__(self):
        super().__init__(daemon=True)
        print(A.q)

    def run(self):
        print(A.q)
4 cũng có thêm các tham số khác, nhưng chúng ta sẽ tìm hiểu nó sau nhé.

Để bắt đầu một tiến trình thì ta gọi đến phương thức start.

Để dừng chương trình tạm thời, tức là chờ hai tiến trình xử lý xong thì ta sử dụng phương thức join.chạy độc lập và có không gian bộ nhớ riêng.

Như vậy đoạn code

from multiprocessing import Process
from class_a import A

class B(Process):

    def __init__(self):
        super().__init__(daemon=True)
        print(A.q)

    def run(self):
        print(A.q)
5 chỉ được thực chạy khi hai tiến trình phía trên hoàn thành.global ở 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.

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

from multiprocessing import Process, Queue

class A(Process):
    q = Queue()

    def __init__(self) -> None:
        super().__init__(daemon=True)
1

Kết quả:

from multiprocessing import Process, Queue

class A(Process):
    q = Queue()

    def __init__(self) -> None:
        super().__init__(daemon=True)
2

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

  • Đoạn code
    from multiprocessing import Process
    from class_a import A
    
    class B(Process):
    
        def __init__(self):
            super().__init__(daemon=True)
            print(A.q)
    
        def run(self):
            print(A.q)
    
    1 dùng để khai báo sử dụng module multiprocessing.
  • Để tạo một process thì ta sử dụng class tên là Process, nó có hai tham số như sau:
  • from multiprocessing import Process
    from class_a import A
    
    class B(Process):
    
        def __init__(self):
            super().__init__(daemon=True)
            print(A.q)
    
        def run(self):
            print(A.q)
    
    2 là hàm được gọi để chạy
  • from multiprocessing import Process
    from class_a import A
    
    class B(Process):
    
        def __init__(self):
            super().__init__(daemon=True)
            print(A.q)
    
        def run(self):
            print(A.q)
    
    3 là các tham số sẽ truyền vào hàm target

Class

from multiprocessing import Process
from class_a import A

class B(Process):

    def __init__(self):
        super().__init__(daemon=True)
        print(A.q)

    def run(self):
        print(A.q)
4 cũng có thêm các tham số khác, nhưng chúng ta sẽ tìm hiểu nó sau nhé.

Để bắt đầu một tiến trình thì ta gọi đến phương thức start.share dữ liệu giữa chúng thì làm thế nào?

Để dừng chương trình tạm thời, tức là chờ hai tiến trình xử lý xong thì ta sử dụng phương thức join.

  • Như vậy đoạn code
    from multiprocessing import Process
    from class_a import A
    
    class B(Process):
    
        def __init__(self):
            super().__init__(daemon=True)
            print(A.q)
    
        def run(self):
            print(A.q)
    
    5 chỉ được thực chạy khi hai tiến trình phía trên hoàn thành.
  • Nếu bạn vẫn chưa hình dung được việc xử lý các tiến trình là riêng biệt thì hãy tham khảo thêm ví dụ 2 dưới đây.
from multiprocessing import Process, Queue

class A(Process):
    q = Queue()

    def __init__(self) -> None:
        super().__init__(daemon=True)
3

Kết quả:

from multiprocessing import Process, Queue

class A(Process):
    q = Queue()

    def __init__(self) -> None:
        super().__init__(daemon=True)
4

Giải thích một chút về chương trình:process1 mình đã thay đổi giá trị cho các đối tượng Array và Value, và nó được lưu lại cho mọi tiến trình chạy sau nó.

Đoạn code

from multiprocessing import Process
from class_a import A

class B(Process):

    def __init__(self):
        super().__init__(daemon=True)
        print(A.q)

    def run(self):
        print(A.q)
1 dùng để khai báo sử dụng module multiprocessing.: 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 multiprocessing 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 hành theo sẽ giúp ích rất nhiều trong việc hiểu về đa tiến trình.