Các hàm quản lý giao diện trong Python

Việc triển khai các giao diện với các lớp cơ sở trừu tượng đơn giản hơn nhiều trong Python 3 hiện đại và chúng phục vụ mục đích như một hợp đồng giao diện cho các phần mở rộng của trình cắm thêm

Show

Tạo giao diện/lớp cơ sở trừu tượng

from abc import ABC, abstractmethod

class AccountingSystem(ABC):

    @abstractmethod
    def create_purchase_invoice(self, purchase):
        pass

    @abstractmethod
    def create_sale_invoice(self, sale):
        log.debug('Creating sale invoice', sale)

Tạo một lớp con bình thường và ghi đè tất cả các phương thức trừu tượng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)

Bạn có thể tùy ý triển khai chung trong các phương thức trừu tượng như trong

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
98, gọi nó bằng
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
99 một cách rõ ràng trong lớp con như trên

Việc khởi tạo một lớp con không triển khai tất cả các phương thức trừu tượng không thành công

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice

Bạn cũng có thể có các thuộc tính trừu tượng, phương thức tĩnh và lớp bằng cách kết hợp các chú thích tương ứng với

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    with Pool(5) as p:
        print(p.map(f, [1, 2, 3]))
00

Các lớp cơ sở trừu tượng rất tốt để triển khai các hệ thống dựa trên plugin. Tất cả các lớp con đã nhập của một lớp đều có thể truy cập được thông qua

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    with Pool(5) as p:
        print(p.map(f, [1, 2, 3]))
01, vì vậy nếu bạn tải tất cả các lớp từ một thư mục plugin bằng
from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    with Pool(5) as p:
        print(p.map(f, [1, 2, 3]))
02 và nếu chúng phân lớp cho lớp cơ sở, thì bạn có quyền truy cập trực tiếp vào chúng thông qua
from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    with Pool(5) as p:
        print(p.map(f, [1, 2, 3]))
01 và bạn có thể chắc chắn rằng hợp đồng giao diện được thực thi

Mô-đun

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6 cũng giới thiệu các API không có tương tự trong mô-đun
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
0. Một ví dụ điển hình của điều này là đối tượng
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
5 cung cấp một phương tiện thuận tiện để song song hóa việc thực thi một hàm trên nhiều giá trị đầu vào, phân phối dữ liệu đầu vào qua các quy trình (song song hóa dữ liệu). Ví dụ sau minh họa cách thực hành phổ biến để xác định các chức năng như vậy trong một mô-đun để các quy trình con có thể nhập thành công mô-đun đó. Ví dụ cơ bản về xử lý song song dữ liệu bằng cách sử dụng
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
5,

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    with Pool(5) as p:
        print(p.map(f, [1, 2, 3]))

sẽ in ra đầu ra tiêu chuẩn

________số 8

Xem thêm

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
7 cung cấp giao diện cấp cao hơn để đẩy các tác vụ sang quy trình nền mà không chặn thực thi quy trình gọi. So với việc sử dụng trực tiếp giao diện
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
5, API
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
9 dễ dàng hơn cho phép tách công việc gửi đến nhóm quy trình cơ bản khỏi việc chờ đợi kết quả

Lớp class GizmoAccountingSystem(AccountingSystem): def create_purchase_invoice(self, purchase): submit_to_gizmo_purchase_service(purchase) def create_sale_invoice(self, sale): super().create_sale_invoice(sale) submit_to_gizmo_sale_service(sale) 20¶

Trong

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6, các quy trình được sinh ra bằng cách tạo một đối tượng
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
20 và sau đó gọi phương thức
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
23 của nó.
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
20 tuân theo API của
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
25. Một ví dụ nhỏ về chương trình đa xử lý là

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
8

Để hiển thị các ID quy trình riêng lẻ có liên quan, đây là một ví dụ mở rộng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
9

Để biết giải thích tại sao phần

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
26 lại cần thiết, hãy xem Hướng dẫn lập trình .

Bối cảnh và phương pháp bắt đầu¶

Tùy thuộc vào nền tảng,

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6 hỗ trợ ba cách để bắt đầu quy trình. Các phương thức bắt đầu này là

đẻ trứng

Quá trình mẹ bắt đầu một quá trình phiên dịch Python mới. Tiến trình con sẽ chỉ kế thừa những tài nguyên cần thiết để chạy phương thức

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
28 của đối tượng tiến trình. Cụ thể, các bộ mô tả và xử lý tệp không cần thiết từ quy trình gốc sẽ không được kế thừa. Bắt đầu một quy trình bằng phương pháp này khá chậm so với sử dụng fork hoặc forkserver

Có sẵn trên Unix và Windows. Mặc định trên Windows và macOS

cái nĩa

Quá trình mẹ sử dụng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
29 để rẽ nhánh trình thông dịch Python. Tiến trình con, khi nó bắt đầu, thực sự giống với tiến trình cha. Tất cả các tài nguyên của cha mẹ được kế thừa bởi tiến trình con. Lưu ý rằng việc rẽ nhánh một cách an toàn một quy trình đa luồng là một vấn đề

Chỉ khả dụng trên Unix. Mặc định trên Unix

máy chủ rẽ nhánh

Khi chương trình bắt đầu và chọn phương thức khởi động máy chủ rẽ nhánh, một quy trình máy chủ sẽ được bắt đầu. Từ đó trở đi, bất cứ khi nào cần một quy trình mới, quy trình mẹ sẽ kết nối với máy chủ và yêu cầu nó rẽ nhánh một quy trình mới. Quá trình máy chủ ngã ba là một luồng nên nó an toàn khi sử dụng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
29. Không có tài nguyên không cần thiết được kế thừa

Có sẵn trên các nền tảng Unix hỗ trợ chuyển bộ mô tả tệp qua các đường ống Unix

Đã thay đổi trong phiên bản 3. 8. Trên macOS, phương thức bắt đầu sinh sản hiện là mặc định. Phương pháp bắt đầu ngã ba nên được coi là không an toàn vì nó có thể dẫn đến sự cố của quy trình con. Xem bpo-33725.

Đã thay đổi trong phiên bản 3. 4. đã thêm spawn trên tất cả các nền tảng Unix và thêm máy chủ phân nhánh cho một số nền tảng Unix. Các tiến trình con không còn kế thừa tất cả các xử lý có thể kế thừa của cha mẹ trên Windows.

Trên Unix, sử dụng các phương thức khởi động spawn hoặc forkserver cũng sẽ bắt đầu quy trình theo dõi tài nguyên theo dõi các tài nguyên hệ thống được đặt tên chưa được liên kết (chẳng hạn như semaphores được đặt tên hoặc đối tượng

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
51) được tạo bởi các quy trình của chương trình. Khi tất cả các quy trình đã thoát, trình theo dõi tài nguyên sẽ hủy liên kết mọi đối tượng được theo dõi còn lại. Thông thường sẽ không có, nhưng nếu một quá trình bị giết bởi một tín hiệu thì có thể có một số tài nguyên "bị rò rỉ". (Các semaphore bị rò rỉ cũng như các phân đoạn bộ nhớ dùng chung sẽ không được tự động hủy liên kết cho đến lần khởi động lại tiếp theo. Đây là vấn đề đối với cả hai đối tượng vì hệ thống chỉ cho phép một số lượng hạn chế các semaphores được đặt tên và các phân đoạn bộ nhớ dùng chung chiếm một số không gian trong bộ nhớ chính. )

Để chọn một phương pháp bắt đầu, bạn sử dụng

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
52 trong mệnh đề
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
26 của mô-đun chính. Ví dụ

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
8

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
52 không nên được sử dụng nhiều hơn một lần trong chương trình

Ngoài ra, bạn có thể sử dụng

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
55 để lấy đối tượng bối cảnh. Các đối tượng ngữ cảnh có API giống như mô-đun đa xử lý và cho phép một người sử dụng nhiều phương thức bắt đầu trong cùng một chương trình

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()

Lưu ý rằng các đối tượng liên quan đến một bối cảnh có thể không tương thích với các quy trình cho một bối cảnh khác. Cụ thể, các khóa được tạo bằng bối cảnh ngã ba không thể được chuyển đến các quy trình được bắt đầu bằng phương pháp bắt đầu sinh sản hoặc máy chủ ngã ba

Một thư viện muốn sử dụng một phương thức bắt đầu cụ thể có lẽ nên sử dụng

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
55 để tránh ảnh hưởng đến sự lựa chọn của người dùng thư viện

Cảnh báo

Các phương thức bắt đầu của

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
57 và
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
58 hiện không thể được sử dụng với các tệp thực thi "đóng băng" (i. e. , các tệp nhị phân được tạo bởi các gói như PyInstaller và cx_Freeze) trên Unix. Phương thức bắt đầu của
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
59 không hoạt động

Trao đổi đối tượng giữa các tiến trình¶

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6 hỗ trợ hai loại kênh liên lạc giữa các quy trình

hàng đợi

Lớp

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
71 gần như là bản sao của lớp
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
72. Ví dụ

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()

Hàng đợi là luồng và xử lý an toàn

ống

Hàm

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
73 trả về một cặp đối tượng kết nối được kết nối bởi một đường ống mà theo mặc định là song công (hai chiều). Ví dụ

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
2

Hai đối tượng kết nối được trả về bởi

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
73 đại diện cho hai đầu của đường ống. Mỗi đối tượng kết nối có các phương thức
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
75 và
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
76 (trong số các phương thức khác). Lưu ý rằng dữ liệu trong một đường ống có thể bị hỏng nếu hai quy trình (hoặc luồng) cố gắng đọc hoặc ghi vào cùng một đầu của đường ống cùng một lúc. Tất nhiên, không có nguy cơ tham nhũng từ các quy trình sử dụng các đầu khác nhau của đường ống cùng một lúc

Đồng bộ hóa giữa các quy trình¶

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6 chứa các giá trị tương đương của tất cả các nguyên mẫu đồng bộ hóa từ
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
0. Chẳng hạn, người ta có thể sử dụng khóa để đảm bảo rằng mỗi lần chỉ có một quy trình in ra đầu ra tiêu chuẩn

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
5

Không sử dụng đầu ra khóa từ các quy trình khác nhau có thể bị lẫn lộn

Chia sẻ trạng thái giữa các tiến trình¶

Như đã đề cập ở trên, khi thực hiện lập trình đồng thời, tốt nhất là tránh sử dụng trạng thái chia sẻ càng nhiều càng tốt. Điều này đặc biệt đúng khi sử dụng nhiều quy trình

Tuy nhiên, nếu bạn thực sự cần sử dụng một số dữ liệu được chia sẻ thì

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6 sẽ cung cấp một số cách để thực hiện việc đó

Bộ nhớ dùng chung

Dữ liệu có thể được lưu trữ trong bản đồ bộ nhớ dùng chung bằng cách sử dụng

[1, 4, 9]
00 hoặc
[1, 4, 9]
01. Ví dụ, đoạn mã sau

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
7

sẽ in

[1, 4, 9]
0

Các đối số

[1, 4, 9]
02 và
[1, 4, 9]
03 được sử dụng khi tạo
[1, 4, 9]
04 và
[1, 4, 9]
05 là các loại mã được sử dụng bởi mô-đun
[1, 4, 9]
06.
[1, 4, 9]
02 biểu thị số float có độ chính xác kép và
[1, 4, 9]
03 biểu thị số nguyên đã ký. Các đối tượng được chia sẻ này sẽ được xử lý và an toàn cho luồng

Để linh hoạt hơn trong việc sử dụng bộ nhớ dùng chung, người ta có thể sử dụng mô-đun

[1, 4, 9]
09 hỗ trợ tạo các đối tượng ctypes tùy ý được phân bổ từ bộ nhớ dùng chung

quy trình máy chủ

Một đối tượng người quản lý được trả về bởi

[1, 4, 9]
10 kiểm soát một quy trình máy chủ chứa các đối tượng Python và cho phép các quy trình khác thao tác chúng bằng proxy

Người quản lý do

[1, 4, 9]
10 trả lại sẽ hỗ trợ các loại
[1, 4, 9]
12,
[1, 4, 9]
13,
[1, 4, 9]
14,
[1, 4, 9]
15,
[1, 4, 9]
16,
[1, 4, 9]
17,
[1, 4, 9]
18,
[1, 4, 9]
19,
[1, 4, 9]
20,
[1, 4, 9]
21,
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
71,
[1, 4, 9]
00 và
[1, 4, 9]
01. Ví dụ,

[1, 4, 9]
1

sẽ in

[1, 4, 9]
2

Trình quản lý quy trình máy chủ linh hoạt hơn so với việc sử dụng các đối tượng bộ nhớ dùng chung vì chúng có thể được tạo để hỗ trợ các loại đối tượng tùy ý. Ngoài ra, một trình quản lý duy nhất có thể được chia sẻ bởi các quy trình trên các máy tính khác nhau qua mạng. Tuy nhiên, chúng chậm hơn so với sử dụng bộ nhớ dùng chung

Sử dụng một nhóm công nhân¶

Lớp

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
5 đại diện cho một nhóm các worker process. Nó có các phương thức cho phép các tác vụ được giảm tải cho các quy trình công nhân theo một số cách khác nhau

Ví dụ

[1, 4, 9]
3

Lưu ý rằng các phương thức của một nhóm chỉ nên được sử dụng bởi quy trình đã tạo ra nó

Ghi chú

Chức năng trong gói này yêu cầu trẻ em có thể nhập mô-đun

[1, 4, 9]
26. Điều này được đề cập trong Hướng dẫn lập trình tuy nhiên nó đáng để chỉ ra ở đây. Điều này có nghĩa là một số ví dụ, chẳng hạn như ví dụ
[1, 4, 9]
27 sẽ không hoạt động trong trình thông dịch tương tác. Ví dụ.

[1, 4, 9]
4

(Nếu bạn thử điều này, nó sẽ thực sự tạo ra ba lần theo dõi đầy đủ được xen kẽ theo kiểu bán ngẫu nhiên, và sau đó bạn có thể phải dừng quá trình gốc bằng cách nào đó. )

Thẩm quyền giải quyết¶

Gói

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6 chủ yếu sao chép API của mô-đun
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
0

class GizmoAccountingSystem(AccountingSystem): def create_purchase_invoice(self, purchase): submit_to_gizmo_purchase_service(purchase) def create_sale_invoice(self, sale): super().create_sale_invoice(sale) submit_to_gizmo_sale_service(sale) 20 và ngoại lệ¶

lớp đa xử lý. Quy trình(nhóm=Không, target=None, name=None, args=(), kwargs={}, *, daemon=None)

Các đối tượng quy trình đại diện cho hoạt động được chạy trong một quy trình riêng biệt. Lớp

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
20 có tương đương với tất cả các phương thức của
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
25

Hàm tạo phải luôn được gọi với các đối số từ khóa. nhóm phải luôn là

[1, 4, 9]
33; . target là đối tượng có thể gọi được gọi bằng phương thức
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
28. Nó mặc định là
[1, 4, 9]
33, nghĩa là không có gì được gọi. name là tên quy trình (xem
[1, 4, 9]
37 để biết thêm chi tiết). args là bộ đối số cho lệnh gọi đích. kwargs là một từ điển các đối số từ khóa cho lệnh gọi đích. Nếu được cung cấp, đối số trình nền chỉ có từ khóa sẽ đặt cờ quy trình
[1, 4, 9]
38 thành
[1, 4, 9]
39 hoặc
[1, 4, 9]
40. Nếu
[1, 4, 9]
33 (mặc định), cờ này sẽ được kế thừa từ quá trình tạo

Theo mặc định, không có đối số nào được chuyển đến đích. Đối số args, mặc định là

[1, 4, 9]
42, có thể được sử dụng để chỉ định một danh sách hoặc bộ đối số để chuyển đến đích

Nếu một lớp con ghi đè hàm tạo, nó phải đảm bảo rằng nó gọi hàm tạo của lớp cơ sở (

[1, 4, 9]
43) trước khi thực hiện bất kỳ điều gì khác đối với quy trình

Đã thay đổi trong phiên bản 3. 3. Đã thêm đối số daemon.

chạy()

Phương thức biểu diễn hoạt động của tiến trình

Bạn có thể ghi đè phương thức này trong một lớp con. Phương thức

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
28 tiêu chuẩn gọi đối tượng có thể gọi được chuyển đến hàm tạo của đối tượng làm đối số đích, nếu có, với các đối số tuần tự và từ khóa được lấy từ các đối số args và kwargs tương ứng

Sử dụng một danh sách hoặc bộ dữ liệu làm đối số args được truyền cho

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
20 cũng đạt được hiệu quả tương tự

Ví dụ

[1, 4, 9]
5

bắt đầu()

Bắt đầu hoạt động của quy trình

Điều này phải được gọi nhiều nhất một lần cho mỗi đối tượng quy trình. Nó sắp xếp để gọi phương thức

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
28 của đối tượng trong một quy trình riêng biệt

tham gia([hết thời gian])

Nếu thời gian chờ của đối số tùy chọn là

[1, 4, 9]
33 (mặc định), phương thức sẽ chặn cho đến khi quá trình có phương thức
[1, 4, 9]
48 được gọi kết thúc. Nếu thời gian chờ là một số dương, nó sẽ chặn tối đa các giây hết thời gian chờ. Lưu ý rằng phương thức trả về
[1, 4, 9]
33 nếu quá trình của nó kết thúc hoặc nếu phương thức hết thời gian chờ. Kiểm tra
[1, 4, 9]
50 của quy trình để xác định xem nó có bị chấm dứt hay không

Một quá trình có thể được tham gia nhiều lần

Một quá trình không thể tự tham gia vì điều này sẽ gây ra bế tắc. Có lỗi khi cố gắng tham gia một quy trình trước khi nó được bắt đầu

tên

Tên quy trình. Tên là một chuỗi chỉ được sử dụng cho mục đích nhận dạng. Nó không có ngữ nghĩa. Nhiều quá trình có thể được đặt tên giống nhau

Tên ban đầu được đặt bởi hàm tạo. Nếu không có tên rõ ràng nào được cung cấp cho hàm tạo, tên có dạng 'Process-N1. N2. …. Nk' được xây dựng, trong đó mỗi Nk là con thứ N của cha mẹ của nó

is_alive()

Trả về xem quá trình có còn hoạt động không

Đại khái, một đối tượng tiến trình tồn tại từ thời điểm phương thức

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
23 trả về cho đến khi tiến trình con kết thúc

daemon

Cờ daemon của tiến trình, một giá trị Boolean. Điều này phải được đặt trước khi

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
23 được gọi

Giá trị ban đầu được kế thừa từ quá trình tạo

Khi một tiến trình thoát, nó sẽ cố gắng chấm dứt tất cả các tiến trình con daemon của nó

Lưu ý rằng quy trình daemon không được phép tạo quy trình con. Mặt khác, một tiến trình daemon sẽ khiến các con của nó mồ côi nếu nó bị chấm dứt khi tiến trình cha của nó thoát ra. Ngoài ra, đây không phải là dịch vụ hoặc daemon Unix, chúng là các quy trình bình thường sẽ bị chấm dứt (và không được tham gia) nếu các quy trình không phải daemon đã thoát

Ngoài API

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
25, các đối tượng
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
20 cũng hỗ trợ các thuộc tính và phương thức sau

pid

Trả lại ID tiến trình. Trước khi quá trình được sinh ra, đây sẽ là

[1, 4, 9]
33

mã thoát

Mã thoát của trẻ. Đây sẽ là

[1, 4, 9]
33 nếu quá trình chưa kết thúc

Nếu phương thức

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
28 của đứa trẻ trả về bình thường, mã thoát sẽ là 0. Nếu nó kết thúc qua
[1, 4, 9]
58 với đối số số nguyên N, thì mã thoát sẽ là N

Nếu đứa trẻ bị chấm dứt do một ngoại lệ không bị bắt trong

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
28, mã thoát sẽ là 1. Nếu nó bị kết thúc bởi tín hiệu N, mã thoát sẽ là giá trị âm -N

khóa xác thực

Khóa xác thực của quy trình (một chuỗi byte)

Khi khởi tạo

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6, quy trình chính được gán một chuỗi ngẫu nhiên bằng cách sử dụng
[1, 4, 9]
61

Khi một đối tượng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
20 được tạo, nó sẽ kế thừa khóa xác thực của quy trình mẹ của nó, mặc dù điều này có thể được thay đổi bằng cách đặt
[1, 4, 9]
63 thành một chuỗi byte khác

Xem Khóa xác thực .

trọng điểm

Một điều khiển số của một đối tượng hệ thống sẽ trở thành "sẵn sàng" khi quá trình kết thúc

Bạn có thể sử dụng giá trị này nếu muốn đợi nhiều sự kiện cùng lúc bằng cách sử dụng

[1, 4, 9]
64. Mặt khác, gọi
[1, 4, 9]
48 đơn giản hơn

Trên Windows, đây là một tay cầm hệ điều hành có thể sử dụng được với nhóm lệnh gọi API

[1, 4, 9]
66 và
[1, 4, 9]
67. Trên Unix, đây là một bộ mô tả tệp có thể sử dụng được với các nguyên mẫu từ mô-đun
[1, 4, 9]
68

Mới trong phiên bản 3. 3

chấm dứt()

Chấm dứt quá trình. Trên Unix, điều này được thực hiện bằng tín hiệu

[1, 4, 9]
69; . Lưu ý rằng các trình xử lý thoát và các mệnh đề cuối cùng, v.v. , sẽ không được thực hiện

Lưu ý rằng các tiến trình con của tiến trình sẽ không bị chấm dứt – chúng sẽ đơn giản trở nên mồ côi

Cảnh báo

Nếu phương pháp này được sử dụng khi quy trình được liên kết đang sử dụng đường ống hoặc hàng đợi thì đường ống hoặc hàng đợi đó có thể bị hỏng và có thể trở nên không sử dụng được bởi quy trình khác. Tương tự, nếu quá trình đã có khóa hoặc semaphore, v.v. sau đó chấm dứt nó có khả năng gây ra bế tắc cho các quá trình khác

giết()

Tương tự như

[1, 4, 9]
71 nhưng sử dụng tín hiệu
[1, 4, 9]
72 trên Unix

Mới trong phiên bản 3. 7

đóng()

Đóng đối tượng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
20, giải phóng tất cả các tài nguyên được liên kết với nó.
[1, 4, 9]
74 được nâng lên nếu quy trình cơ bản vẫn đang chạy. Khi
[1, 4, 9]
75 trả về thành công, hầu hết các phương thức và thuộc tính khác của đối tượng
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
20 sẽ tăng
[1, 4, 9]
74

Mới trong phiên bản 3. 7

Lưu ý rằng các phương thức

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
23,
[1, 4, 9]
48,
[1, 4, 9]
80,
[1, 4, 9]
71 và
[1, 4, 9]
50 chỉ nên được gọi bởi quy trình đã tạo đối tượng quy trình

Ví dụ sử dụng một số phương pháp của

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
20

[1, 4, 9]
6

ngoại lệ đa xử lý. Lỗi quy trình

Lớp cơ sở của tất cả các ngoại lệ

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6

ngoại lệ đa xử lý. BufferTooShort

Ngoại lệ được đưa ra bởi

[1, 4, 9]
85 khi đối tượng bộ đệm được cung cấp quá nhỏ để đọc thông báo

Nếu

[1, 4, 9]
86 là một phiên bản của
[1, 4, 9]
87 thì
[1, 4, 9]
88 sẽ đưa ra thông báo dưới dạng chuỗi byte

ngoại lệ đa xử lý. Lỗi xác thực

Xảy ra khi có lỗi xác thực

ngoại lệ đa xử lý. Lỗi hết giờ

Tăng theo các phương thức có thời gian chờ khi hết thời gian chờ

Đường ống và hàng đợi¶

Khi sử dụng nhiều quy trình, người ta thường sử dụng tính năng truyền thông báo để liên lạc giữa các quy trình và tránh phải sử dụng bất kỳ nguyên tắc đồng bộ hóa nào như khóa

Để truyền tin nhắn, người ta có thể sử dụng

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
73 (để kết nối giữa hai quy trình) hoặc hàng đợi (cho phép nhiều nhà sản xuất và người tiêu dùng)

Các loại

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
71,
[1, 4, 9]
91 và
[1, 4, 9]
92 là hàng đợi FIFO nhiều nhà sản xuất, nhiều người tiêu dùng được mô hình hóa trên lớp
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
72 trong thư viện tiêu chuẩn. Chúng khác nhau ở chỗ
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
71 thiếu các phương thức
[1, 4, 9]
95 và
[1, 4, 9]
48 được đưa vào Python 2. lớp 5 của
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
72

Nếu bạn sử dụng

[1, 4, 9]
92 thì bạn phải gọi
[1, 4, 9]
99 cho mỗi tác vụ bị xóa khỏi hàng đợi, nếu không, semaphore được sử dụng để đếm số lượng tác vụ chưa hoàn thành cuối cùng có thể bị tràn, gây ra ngoại lệ

Lưu ý rằng một người cũng có thể tạo hàng đợi dùng chung bằng cách sử dụng đối tượng người quản lý – xem Người quản lý .

Ghi chú

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6 sử dụng các ngoại lệ
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
801 và
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
802 thông thường để báo hiệu thời gian chờ. Chúng không có sẵn trong không gian tên
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6 nên bạn cần nhập chúng từ
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
804

Ghi chú

Khi một đối tượng được đưa vào hàng đợi, đối tượng đó sẽ được chọn và một chuỗi nền sau đó sẽ xóa dữ liệu đã chọn vào một đường dẫn bên dưới. Điều này có một số hậu quả hơi ngạc nhiên, nhưng sẽ không gây ra bất kỳ khó khăn thực tế nào – nếu chúng thực sự làm phiền bạn thì thay vào đó, bạn có thể sử dụng hàng đợi được tạo bằng trình quản lý.

  1. Sau khi đặt một đối tượng vào hàng đợi trống, có thể có độ trễ vô cùng nhỏ trước khi phương thức

    class GizmoAccountingSystem(AccountingSystem):
    
        def create_purchase_invoice(self, purchase):
            submit_to_gizmo_purchase_service(purchase)
    
        def create_sale_invoice(self, sale):
            super().create_sale_invoice(sale)
            submit_to_gizmo_sale_service(sale)
    
    805 của hàng đợi trả về
    [1, 4, 9]
    
    40 và
    class GizmoAccountingSystem(AccountingSystem):
    
        def create_purchase_invoice(self, purchase):
            submit_to_gizmo_purchase_service(purchase)
    
        def create_sale_invoice(self, sale):
            super().create_sale_invoice(sale)
            submit_to_gizmo_sale_service(sale)
    
    807 có thể trả về mà không cần tăng
    class GizmoAccountingSystem(AccountingSystem):
    
        def create_purchase_invoice(self, purchase):
            submit_to_gizmo_purchase_service(purchase)
    
        def create_sale_invoice(self, sale):
            super().create_sale_invoice(sale)
            submit_to_gizmo_sale_service(sale)
    
    801

  2. Nếu nhiều quá trình đang xếp hàng các đối tượng, thì có thể các đối tượng được nhận ở đầu kia không theo thứ tự. Tuy nhiên, các đối tượng được xử lý bởi cùng một quy trình sẽ luôn theo thứ tự mong đợi đối với nhau

Cảnh báo

Nếu một quá trình bị giết bằng cách sử dụng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
809 hoặc
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
810 trong khi nó đang cố gắng sử dụng một
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
71, thì dữ liệu trong hàng đợi có khả năng bị hỏng. Điều này có thể khiến bất kỳ quy trình nào khác gặp ngoại lệ khi nó cố sử dụng hàng đợi sau này

Cảnh báo

Như đã đề cập ở trên, nếu một tiến trình con đã đặt các mục vào hàng đợi (và nó chưa sử dụng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
812), thì tiến trình đó sẽ không kết thúc cho đến khi tất cả các mục trong bộ đệm đã được chuyển vào đường ống

Điều này có nghĩa là nếu bạn cố gắng tham gia quá trình đó, bạn có thể gặp bế tắc trừ khi bạn chắc chắn rằng tất cả các mục được đưa vào hàng đợi đã được sử dụng hết. Tương tự, nếu tiến trình con không phải daemon thì tiến trình cha có thể bị treo khi thoát khi nó cố gắng nối tất cả các con không phải daemon của nó

Lưu ý rằng hàng đợi được tạo bằng trình quản lý không gặp sự cố này. Xem Hướng dẫn lập trình .

Để biết ví dụ về việc sử dụng hàng đợi để liên lạc giữa các quá trình, hãy xem Ví dụ .

đa xử lý. Đường ống([song công])

Trả về một cặp

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
813 của các đối tượng
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
814 đại diện cho các đầu của một đường ống

Nếu song công là

[1, 4, 9]
39 (mặc định) thì đường ống là hai chiều. Nếu song công là
[1, 4, 9]
40 thì đường ống là một chiều.
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
817 chỉ có thể được sử dụng để nhận tin nhắn và
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
818 chỉ có thể được sử dụng để gửi tin nhắn

lớp đa xử lý. Hàng đợi([kích thước tối đa])

Trả về một hàng đợi chia sẻ quy trình được thực hiện bằng cách sử dụng một đường ống và một vài ổ khóa/semaphores. Khi một quy trình lần đầu tiên đặt một mục vào hàng đợi, một chuỗi trung chuyển được bắt đầu để chuyển các đối tượng từ bộ đệm vào đường ống

Các ngoại lệ

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
801 và
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
802 thông thường từ mô-đun
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
804 của thư viện tiêu chuẩn được nâng lên để báo hiệu thời gian chờ

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
71 thực hiện tất cả các phương pháp của
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
72 ngoại trừ
[1, 4, 9]
95 và
[1, 4, 9]
48

qsize()

Trả về kích thước gần đúng của hàng đợi. Do ngữ nghĩa đa luồng/đa xử lý, con số này không đáng tin cậy

Lưu ý rằng điều này có thể làm tăng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
826 trên các nền tảng Unix như macOS nơi
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
827 không được triển khai

trống()

Trả lại

[1, 4, 9]
39 nếu hàng đợi trống, ngược lại là
[1, 4, 9]
40. Do ngữ nghĩa đa luồng/đa xử lý, điều này không đáng tin cậy

đầy đủ()

Trả lại

[1, 4, 9]
39 nếu hàng đợi đã đầy, ngược lại là
[1, 4, 9]
40. Do ngữ nghĩa đa luồng/đa xử lý, điều này không đáng tin cậy

đặt(obj[ , block[, timeout]])

Đặt obj vào hàng đợi. Nếu khối đối số tùy chọn là

[1, 4, 9]
39 (mặc định) và thời gian chờ là
[1, 4, 9]
33 (mặc định), hãy chặn nếu cần cho đến khi có chỗ trống. Nếu thời gian chờ là một số dương, nó sẽ chặn tối đa các giây hết thời gian chờ và tăng ngoại lệ
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
802 nếu không có chỗ trống trong thời gian đó. Mặt khác (khối là
[1, 4, 9]
40), hãy đặt một mục vào hàng đợi nếu có sẵn một vị trí trống ngay lập tức, nếu không thì tăng ngoại lệ
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
802 (thời gian chờ bị bỏ qua trong trường hợp đó)

Changed in version 3. 8. Nếu hàng đợi đã đóng,

[1, 4, 9]
74 được nâng lên thay vì
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
838.

put_nowait(obj)

Equivalent to

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
839

get([block[ , timeout]])

Remove and return an item from the queue. If optional args block is

[1, 4, 9]
39 (the default) and timeout is
[1, 4, 9]
33 (the default), block if necessary until an item is available. If timeout is a positive number, it blocks at most timeout seconds and raises the
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
801 exception if no item was available within that time. Otherwise (block is
[1, 4, 9]
40), return an item if one is immediately available, else raise the
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
801 exception (timeout is ignored in that case)

Changed in version 3. 8. If the queue is closed,

[1, 4, 9]
74 is raised instead of
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
846.

get_nowait()

Equivalent to

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
847

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
848 has a few additional methods not found in
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
72. These methods are usually unnecessary for most code

đóng()

Cho biết rằng quy trình hiện tại sẽ không đưa thêm dữ liệu vào hàng đợi này. The background thread will quit once it has flushed all buffered data to the pipe. This is called automatically when the queue is garbage collected

join_thread()

Join the background thread. Điều này chỉ có thể được sử dụng sau khi

[1, 4, 9]
75 đã được gọi. Nó chặn cho đến khi luồng nền thoát ra, đảm bảo rằng tất cả dữ liệu trong bộ đệm đã được chuyển sang đường ống

Theo mặc định, nếu một quy trình không phải là người tạo hàng đợi thì khi thoát, nó sẽ cố gắng tham gia luồng nền của hàng đợi. Quá trình có thể gọi ________ 1851 để khiến ________ 1852 không làm gì cả

cancel_join_thread()

Ngăn chặn

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
852 chặn. Đặc biệt, điều này ngăn luồng nền tự động được nối khi quá trình thoát – xem
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
852

Tên tốt hơn cho phương pháp này có thể là

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
855. Nó có khả năng làm mất dữ liệu trong hàng đợi và bạn gần như chắc chắn sẽ không cần sử dụng nó. Nó thực sự chỉ ở đó nếu bạn cần quy trình hiện tại thoát ngay lập tức mà không cần chờ xóa dữ liệu đã xử lý vào đường ống bên dưới và bạn không quan tâm đến dữ liệu bị mất

Ghi chú

Chức năng của lớp này yêu cầu triển khai semaphore được chia sẻ chức năng trên hệ điều hành máy chủ. Nếu không có, chức năng trong lớp này sẽ bị vô hiệu hóa và cố gắng khởi tạo một

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
71 sẽ dẫn đến một
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
857. Xem bpo-3770 để biết thêm thông tin. Điều này cũng đúng với bất kỳ loại hàng đợi chuyên biệt nào được liệt kê bên dưới

lớp đa xử lý. Queue đơn giản

Nó là loại

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
71 được đơn giản hóa, rất gần với loại
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
859 bị khóa

đóng()

Đóng hàng đợi. giải phóng nội lực

Một hàng đợi không được sử dụng nữa sau khi nó bị đóng. Ví dụ: các phương thức

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
860,
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
861 và
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
805 không còn được gọi nữa

Mới trong phiên bản 3. 9

trống()

Trả lại

[1, 4, 9]
39 nếu hàng đợi trống, ngược lại là
[1, 4, 9]
40

lấy()

Xóa và trả lại một mục khỏi hàng đợi

đặt(mục)

Đặt mục vào hàng đợi

lớp đa xử lý. JoinableQueue([kích thước tối đa])

[1, 4, 9]
92, một lớp con của
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
71, là một hàng đợi có thêm các phương thức
[1, 4, 9]
95 và
[1, 4, 9]
48

task_done()

Chỉ ra rằng một nhiệm vụ được xử lý trước đây đã hoàn thành. Được sử dụng bởi người tiêu dùng xếp hàng. Đối với mỗi

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
860 được sử dụng để tìm nạp một tác vụ, một cuộc gọi tiếp theo tới
[1, 4, 9]
95 sẽ báo cho hàng đợi rằng quá trình xử lý tác vụ đã hoàn tất

Nếu một

[1, 4, 9]
48 hiện đang bị chặn, nó sẽ tiếp tục khi tất cả các mục đã được xử lý (có nghĩa là đã nhận được lệnh gọi
[1, 4, 9]
95 cho mọi mục đã được
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
861 vào hàng đợi)

Tăng

[1, 4, 9]
74 nếu được gọi nhiều lần hơn số vật phẩm được đặt trong hàng đợi

tham gia()

Chặn cho đến khi tất cả các mục trong hàng đợi đã được nhận và xử lý

Số lượng nhiệm vụ chưa hoàn thành tăng lên bất cứ khi nào một mục được thêm vào hàng đợi. Số lượng giảm xuống bất cứ khi nào người tiêu dùng gọi

[1, 4, 9]
95 để cho biết rằng mặt hàng đã được lấy và mọi công việc trên mặt hàng đó đã hoàn tất. Khi số nhiệm vụ chưa hoàn thành giảm xuống 0,
[1, 4, 9]
48 sẽ bỏ chặn

Điều khoản khác¶

đa xử lý. active_children()

Trả về danh sách tất cả các phần tử con còn sống của tiến trình hiện tại

Gọi điều này có tác dụng phụ là “tham gia” bất kỳ quy trình nào đã kết thúc

đa xử lý. số lượng cpu()

Trả về số lượng CPU trong hệ thống

Con số này không tương đương với số lượng CPU mà tiến trình hiện tại có thể sử dụng. Số lượng CPU có thể sử dụng có thể thu được với

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
877

Khi không xác định được số lượng CPU, một

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
826 được nâng lên

Xem thêm

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
879

đa xử lý. current_ process()

Trả về đối tượng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
20 tương ứng với quy trình hiện tại

Tương tự của

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
881

đa xử lý. parent_process()

Trả về đối tượng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
20 tương ứng với tiến trình cha của
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
883. Đối với quy trình chính,
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
884 sẽ là
[1, 4, 9]
33

Mới trong phiên bản 3. 8

đa xử lý. freeze_support()

Thêm hỗ trợ khi chương trình sử dụng

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6 bị đóng băng để tạo tệp thực thi Windows. (Đã được thử nghiệm với py2exe, PyInstaller và cx_Freeze. )

Người ta cần gọi hàm này ngay sau dòng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
26 của mô-đun chính. Ví dụ

[1, 4, 9]
7

Nếu dòng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
888 bị bỏ qua thì cố gắng chạy tệp thực thi bị đóng băng sẽ tăng
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
889

Gọi

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
888 không có hiệu lực khi được gọi trên bất kỳ hệ điều hành nào khác ngoài Windows. Ngoài ra, nếu mô-đun đang được trình thông dịch Python trên Windows chạy bình thường (chương trình chưa bị đóng băng) thì
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
888 không có hiệu lực

đa xử lý. get_all_start_methods()

Trả về danh sách các phương thức bắt đầu được hỗ trợ, phương thức đầu tiên là mặc định. Các phương pháp bắt đầu có thể là

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
59,
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
57 và
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
58. Trên Windows chỉ có sẵn
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
57. Trên Unix,
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
59 và
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
57 luôn được hỗ trợ, với
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
59 là mặc định

Mới trong phiên bản 3. 4

đa xử lý. get_context(method=None)

Return a context object which has the same attributes as the

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6 module

Nếu phương thức là

[1, 4, 9]
33 thì ngữ cảnh mặc định được trả về. Mặt khác, phương thức phải là
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
59,
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
57,
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
58.
[1, 4, 9]
74 được nâng lên nếu phương thức bắt đầu được chỉ định không khả dụng

Mới trong phiên bản 3. 4

đa xử lý. get_start_method(allow_none=Sai)

Trả về tên của phương thức bắt đầu được sử dụng để bắt đầu các quy trình

Nếu phương thức bắt đầu chưa được sửa và allow_none là sai, thì phương thức bắt đầu được sửa thành mặc định và tên được trả về. Nếu phương thức bắt đầu chưa được sửa và allow_none là đúng thì trả về

[1, 4, 9]
33

Giá trị trả về có thể là

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
59,
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
57,
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
58 hoặc
[1, 4, 9]
33.
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
59 là mặc định trên Unix, trong khi
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
57 là mặc định trên Windows và macOS

Đã thay đổi trong phiên bản 3. 8. Trên macOS, phương thức bắt đầu sinh sản hiện là mặc định. Phương pháp bắt đầu ngã ba nên được coi là không an toàn vì nó có thể dẫn đến sự cố của quy trình con. Xem bpo-33725.

Mới trong phiên bản 3. 4

multiprocessing. set_executable(executable)

Set the path of the Python interpreter to use when starting a child process. (By default

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
912 is used). Embedders will probably need to do some thing like

[1, 4, 9]
8

before they can create child processes

Changed in version 3. 4. Now supported on Unix when the

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
57 start method is used.

Changed in version 3. 11. Accepts a path-like object .

multiprocessing. set_start_method(method , force=False)

Set the method which should be used to start child processes. The method argument can be

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
59,
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
57 or
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
58. Raises
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
889 if the start method has already been set and force is not
[1, 4, 9]
39. If method is
[1, 4, 9]
33 and force is
[1, 4, 9]
39 then the start method is set to
[1, 4, 9]
33. If method is
[1, 4, 9]
33 and force is
[1, 4, 9]
40 then the context is set to the default context

Note that this should be called at most once, and it should be protected inside the

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
26 clause of the main module

Mới trong phiên bản 3. 4

Ghi chú

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6 contains no analogues of
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
926,
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
927,
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
928,
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
929,
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
930, or
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
931

Connection Objects¶

Connection objects allow the sending and receiving of picklable objects or strings. They can be thought of as message oriented connected sockets

Connection objects are usually created using

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
859 – see also Listeners and Clients .

class multiprocessing. connection. Connectionsend(obj)

Send an object to the other end of the connection which should be read using

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
76

The object must be picklable. Very large pickles (approximately 32 MiB+, though it depends on the OS) may raise a

[1, 4, 9]
74 exception

recv()

Return an object sent from the other end of the connection using

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
75. Blocks until there is something to receive. Raises
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
936 if there is nothing left to receive and the other end was closed

fileno()

Return the file descriptor or handle used by the connection

đóng()

Close the connection

Điều này được gọi tự động khi kết nối được thu gom rác

poll([timeout])

Return whether there is any data available to be read

If timeout is not specified then it will return immediately. If timeout is a number then this specifies the maximum time in seconds to block. If timeout is

[1, 4, 9]
33 then an infinite timeout is used

Note that multiple connection objects may be polled at once by using

[1, 4, 9]
64

send_bytes(buffer[ , offset[ , size]])

Send byte data from a bytes-like object as a complete message.

If offset is given then data is read from that position in buffer. If size is given then that many bytes will be read from buffer. Very large buffers (approximately 32 MiB+, though it depends on the OS) may raise a

[1, 4, 9]
74 exception

recv_bytes([maxlength])

Return a complete message of byte data sent from the other end of the connection as a string. Blocks until there is something to receive. Raises

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
936 if there is nothing left to receive and the other end has closed

If maxlength is specified and the message is longer than maxlength then

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
846 is raised and the connection will no longer be readable

Changed in version 3. 3. This function used to raise

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
942, which is now an alias of
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
846.

recv_bytes_into(buffer[ , offset])

Read into buffer a complete message of byte data sent from the other end of the connection and return the number of bytes in the message. Blocks until there is something to receive. Raises

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
936 if there is nothing left to receive and the other end was closed

buffer must be a writable bytes-like object . If offset is given then the message will be written into the buffer from that position. Offset must be a non-negative integer less than the length of buffer (in bytes).

If the buffer is too short then a

[1, 4, 9]
87 exception is raised and the complete message is available as
[1, 4, 9]
88 where
[1, 4, 9]
86 is the exception instance

Changed in version 3. 3. Connection objects themselves can now be transferred between processes using

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
948 and
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
949.

New in version 3. 3. Connection objects now support the context management protocol – see Context Manager Types .

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
950 returns the connection object, and
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
951 calls
[1, 4, 9]
75.

Ví dụ

[1, 4, 9]
9

Cảnh báo

The

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
949 method automatically unpickles the data it receives, which can be a security risk unless you can trust the process which sent the message

Therefore, unless the connection object was produced using

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
73 you should only use the
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
76 and
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
75 methods after performing some sort of authentication. See Authentication keys .

Cảnh báo

If a process is killed while it is trying to read or write to a pipe then the data in the pipe is likely to become corrupted, because it may become impossible to be sure where the message boundaries lie

Synchronization primitives¶

Generally synchronization primitives are not as necessary in a multiprocess program as they are in a multithreaded program. See the documentation for

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
0 module

Note that one can also create synchronization primitives by using a manager object – see Managers .

class multiprocessing. Barrier(parties[ , action[ , timeout]])

A barrier object. a clone of

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
958

Mới trong phiên bản 3. 3

class multiprocessing. BoundedSemaphore([giá trị])

A bounded semaphore object. a close analog of

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
959

A solitary difference from its close analog exists. its

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
960 method’s first argument is named block, as is consistent with
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
961

Ghi chú

On macOS, this is indistinguishable from

[1, 4, 9]
17 because
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
827 is not implemented on that platform

class multiprocessing. Condition([lock])

A condition variable. an alias for

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
964

If lock is specified then it should be a

[1, 4, 9]
15 or
[1, 4, 9]
16 object from
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6

Changed in version 3. 3. The

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
968 method was added.

class multiprocessing. Event

A clone of

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
969

class multiprocessing. Lock

A non-recursive lock object. a close analog of

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
970. Once a process or thread has acquired a lock, subsequent attempts to acquire it from any process or thread will block until it is released; any process or thread may release it. The concepts and behaviors of
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
970 as it applies to threads are replicated here in
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
972 as it applies to either processes or threads, except as noted

Note that

[1, 4, 9]
15 is actually a factory function which returns an instance of
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
974 initialized with a default context

[1, 4, 9]
15 supports the context manager protocol and thus may be used in
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
976 statements.

acquire(block=True , timeout=None)

Acquire a lock, blocking or non-blocking

With the block argument set to

[1, 4, 9]
39 (the default), the method call will block until the lock is in an unlocked state, then set it to locked and return
[1, 4, 9]
39. Note that the name of this first argument differs from that in
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
979

With the block argument set to

[1, 4, 9]
40, the method call does not block. If the lock is currently in a locked state, return
[1, 4, 9]
40; otherwise set the lock to a locked state and return
[1, 4, 9]
39

When invoked with a positive, floating-point value for timeout, block for at most the number of seconds specified by timeout as long as the lock can not be acquired. Invocations with a negative value for timeout are equivalent to a timeout of zero. Invocations with a timeout value of

[1, 4, 9]
33 (the default) set the timeout period to infinite. Note that the treatment of negative or
[1, 4, 9]
33 values for timeout differs from the implemented behavior in
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
979. The timeout argument has no practical implications if the block argument is set to
[1, 4, 9]
40 and is thus ignored. Returns
[1, 4, 9]
39 if the lock has been acquired or
[1, 4, 9]
40 if the timeout period has elapsed

release()

Release a lock. This can be called from any process or thread, not only the process or thread which originally acquired the lock

Behavior is the same as in

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
989 except that when invoked on an unlocked lock, a
[1, 4, 9]
74 is raised

class multiprocessing. RLock

A recursive lock object. a close analog of

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
991. A recursive lock must be released by the process or thread that acquired it. Once a process or thread has acquired a recursive lock, the same process or thread may acquire it again without blocking; that process or thread must release it once for each time it has been acquired

Note that

[1, 4, 9]
16 is actually a factory function which returns an instance of
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
993 initialized with a default context

[1, 4, 9]
16 supports the context manager protocol and thus may be used in
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
976 statements.

acquire(block=True , timeout=None)

Acquire a lock, blocking or non-blocking

When invoked with the block argument set to

[1, 4, 9]
39, block until the lock is in an unlocked state (not owned by any process or thread) unless the lock is already owned by the current process or thread. The current process or thread then takes ownership of the lock (if it does not already have ownership) and the recursion level inside the lock increments by one, resulting in a return value of
[1, 4, 9]
39. Note that there are several differences in this first argument’s behavior compared to the implementation of
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
998, starting with the name of the argument itself

When invoked with the block argument set to

[1, 4, 9]
40, do not block. If the lock has already been acquired (and thus is owned) by another process or thread, the current process or thread does not take ownership and the recursion level within the lock is not changed, resulting in a return value of
[1, 4, 9]
40. Nếu khóa ở trạng thái không khóa, quy trình hoặc luồng hiện tại sẽ có quyền sở hữu và mức đệ quy được tăng lên, dẫn đến giá trị trả về là
[1, 4, 9]
39

Use and behaviors of the timeout argument are the same as in

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
961. Note that some of these behaviors of timeout differ from the implemented behaviors in
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
998

release()

Release a lock, decrementing the recursion level. If after the decrement the recursion level is zero, reset the lock to unlocked (not owned by any process or thread) and if any other processes or threads are blocked waiting for the lock to become unlocked, allow exactly one of them to proceed. If after the decrement the recursion level is still nonzero, the lock remains locked and owned by the calling process or thread

Only call this method when the calling process or thread owns the lock. An

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
838 is raised if this method is called by a process or thread other than the owner or if the lock is in an unlocked (unowned) state. Note that the type of exception raised in this situation differs from the implemented behavior in
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
805

class multiprocessing. Semaphore([value])

A semaphore object. a close analog of

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
806

A solitary difference from its close analog exists. its

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
960 method’s first argument is named block, as is consistent with
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
961

Ghi chú

On macOS,

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
809 is unsupported, so calling
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
810 with a timeout will emulate that function’s behavior using a sleeping loop

Ghi chú

If the SIGINT signal generated by Ctrl-C arrives while the main thread is blocked by a call to

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
811,
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
961,
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
813,
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
814,
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
815 or
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
816 then the call will be immediately interrupted and
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
817 will be raised

This differs from the behaviour of

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
0 where SIGINT will be ignored while the equivalent blocking calls are in progress

Ghi chú

Some of this package’s functionality requires a functioning shared semaphore implementation on the host operating system. Without one, the

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
819 module will be disabled, and attempts to import it will result in an
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
857. See bpo-3770 for additional information

Shared class IncompleteAccountingSystem(AccountingSystem): pass >>> accounting = IncompleteAccountingSystem() Traceback (most recent call last): File "", line 1, in TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods create_purchase_invoice, create_sale_invoice 821 Objects¶

It is possible to create shared objects using shared memory which can be inherited by child processes

multiprocessing. Value(typecode_or_type , *args , lock=True)

Return a

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
821 object allocated from shared memory. By default the return value is actually a synchronized wrapper for the object. The object itself can be accessed via the value attribute of a
[1, 4, 9]
00

typecode_or_type determines the type of the returned object. it is either a ctypes type or a one character typecode of the kind used by the

[1, 4, 9]
06 module. *args is passed on to the constructor for the type

If lock is

[1, 4, 9]
39 (the default) then a new recursive lock object is created to synchronize access to the value. If lock is a
[1, 4, 9]
15 or
[1, 4, 9]
16 object then that will be used to synchronize access to the value. If lock is
[1, 4, 9]
40 then access to the returned object will not be automatically protected by a lock, so it will not necessarily be “process-safe”

Operations like

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
829 which involve a read and write are not atomic. So if, for instance, you want to atomically increment a shared value it is insufficient to just do

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
80

Assuming the associated lock is recursive (which it is by default) you can instead do

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
81

Note that lock is a keyword-only argument

multiprocessing. Array(typecode_or_type , size_or_initializer , * , lock=True)

Return a ctypes array allocated from shared memory. By default the return value is actually a synchronized wrapper for the array

typecode_or_type determines the type of the elements of the returned array. it is either a ctypes type or a one character typecode of the kind used by the

[1, 4, 9]
06 module. If size_or_initializer is an integer, then it determines the length of the array, and the array will be initially zeroed. Mặt khác, size_or_initializer là một chuỗi được sử dụng để khởi tạo mảng và độ dài của nó xác định độ dài của mảng

If lock is

[1, 4, 9]
39 (the default) then a new lock object is created to synchronize access to the value. If lock is a
[1, 4, 9]
15 or
[1, 4, 9]
16 object then that will be used to synchronize access to the value. If lock is
[1, 4, 9]
40 then access to the returned object will not be automatically protected by a lock, so it will not necessarily be “process-safe”

Note that lock is a keyword only argument

Note that an array of

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
835 has value and raw attributes which allow one to use it to store and retrieve strings

The
[1, 4, 9]
09 module¶

Mô-đun

[1, 4, 9]
09 cung cấp các chức năng để phân bổ các đối tượng
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
821 từ bộ nhớ dùng chung có thể được kế thừa bởi các tiến trình con

Ghi chú

Although it is possible to store a pointer in shared memory remember that this will refer to a location in the address space of a specific process. However, the pointer is quite likely to be invalid in the context of a second process and trying to dereference the pointer from the second process may cause a crash

multiprocessing. sharedctypes. RawArray(typecode_or_type , size_or_initializer)

Return a ctypes array allocated from shared memory

typecode_or_type determines the type of the elements of the returned array. it is either a ctypes type or a one character typecode of the kind used by the

[1, 4, 9]
06 module. If size_or_initializer is an integer then it determines the length of the array, and the array will be initially zeroed. Otherwise size_or_initializer is a sequence which is used to initialize the array and whose length determines the length of the array

Note that setting and getting an element is potentially non-atomic – use

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
840 instead to make sure that access is automatically synchronized using a lock

multiprocessing. sharedctypes. RawValue(typecode_or_type , *args)

Return a ctypes object allocated from shared memory

typecode_or_type determines the type of the returned object. it is either a ctypes type or a one character typecode of the kind used by the

[1, 4, 9]
06 module. *args is passed on to the constructor for the type

Note that setting and getting the value is potentially non-atomic – use

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
842 instead to make sure that access is automatically synchronized using a lock

Note that an array of

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
835 has
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
844 and
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
845 attributes which allow one to use it to store and retrieve strings – see documentation for
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
821

multiprocessing. sharedctypes. Array(typecode_or_type , size_or_initializer , * , lock=True)

The same as

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
847 except that depending on the value of lock a process-safe synchronization wrapper may be returned instead of a raw ctypes array

If lock is

[1, 4, 9]
39 (the default) then a new lock object is created to synchronize access to the value. If lock is a
[1, 4, 9]
15 or
[1, 4, 9]
16 object then that will be used to synchronize access to the value. If lock is
[1, 4, 9]
40 then access to the returned object will not be automatically protected by a lock, so it will not necessarily be “process-safe”

Note that lock is a keyword-only argument

multiprocessing. sharedctypes. Value(typecode_or_type , *args , lock=True)

The same as

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
852 except that depending on the value of lock a process-safe synchronization wrapper may be returned instead of a raw ctypes object

If lock is

[1, 4, 9]
39 (the default) then a new lock object is created to synchronize access to the value. If lock is a
[1, 4, 9]
15 or
[1, 4, 9]
16 object then that will be used to synchronize access to the value. If lock is
[1, 4, 9]
40 then access to the returned object will not be automatically protected by a lock, so it will not necessarily be “process-safe”

Note that lock is a keyword-only argument

multiprocessing. sharedctypes. copy(obj)

Return a ctypes object allocated from shared memory which is a copy of the ctypes object obj

multiprocessing. sharedctypes. synchronized(obj[ , lock])

Return a process-safe wrapper object for a ctypes object which uses lock to synchronize access. If lock is

[1, 4, 9]
33 (the default) then a
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
858 object is created automatically

A synchronized wrapper will have two methods in addition to those of the object it wraps.

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
859 returns the wrapped object and
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
860 returns the lock object used for synchronization

Note that accessing the ctypes object through the wrapper can be a lot slower than accessing the raw ctypes object

Changed in version 3. 5. Synchronized objects support the context manager protocol.

The table below compares the syntax for creating shared ctypes objects from shared memory with the normal ctypes syntax. (In the table

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
861 is some subclass of
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
862. )

ctypes

sharedctypes using type

sharedctypes using typecode

c_double(2. 4)

RawValue(c_double, 2. 4)

RawValue(‘d’, 2. 4)

MyStruct(4, 6)

RawValue(MyStruct, 4, 6)

(c_short * 7)()

RawArray(c_short, 7)

RawArray(‘h’, 7)

(c_int * 3)(9, 2, 8)

RawArray(c_int, (9, 2, 8))

RawArray(‘i’, (9, 2, 8))

Below is an example where a number of ctypes objects are modified by a child process

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
82

The results printed are

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
83

Managers¶

Managers provide a way to create data which can be shared between different processes, including sharing over a network between processes running on different machines. A manager object controls a server process which manages shared objects. Other processes can access the shared objects by using proxies

multiprocessing. Manager()

Returns a started

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
863 object which can be used for sharing objects between processes. The returned manager object corresponds to a spawned child process and has methods which will create shared objects and return corresponding proxies

Manager processes will be shutdown as soon as they are garbage collected or their parent process exits. The manager classes are defined in the

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
864 module

lớp đa xử lý. managers. BaseManager(address=None , authkey=None , serializer='pickle' , ctx=None , * , shutdown_timeout=1. 0)

Create a BaseManager object

Once created one should call

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
23 or
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
866 to ensure that the manager object refers to a started manager process

address is the address on which the manager process listens for new connections. If address is

[1, 4, 9]
33 then an arbitrary one is chosen

authkey is the authentication key which will be used to check the validity of incoming connections to the server process. If authkey is

[1, 4, 9]
33 then
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
869 is used. Otherwise authkey is used and it must be a byte string

serializer must be

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
870 (use
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
871 serialization) or
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
872 (use
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
873 serialization)

ctx is a context object, or

[1, 4, 9]
33 (use the current context). See the
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
55 function

shutdown_timeout is a timeout in seconds used to wait until the process used by the manager completes in the

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
876 method. Nếu hết thời gian tắt máy, quá trình kết thúc. If terminating the process also times out, the process is killed

Changed in version 3. 11. Đã thêm thông số shutdown_timeout.

start([initializer[ , initargs]])

Bắt đầu một quy trình con để khởi động trình quản lý. Nếu bộ khởi tạo không phải là

[1, 4, 9]
33 thì quy trình con sẽ gọi
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
878 khi nó bắt đầu

get_server()

Trả về một đối tượng

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
879 đại diện cho máy chủ thực dưới sự kiểm soát của Trình quản lý. Đối tượng
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
879 hỗ trợ phương thức
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
881

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
84

Ngoài ra,

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
879 còn có thuộc tính
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
883

kết nối()

Kết nối đối tượng quản lý cục bộ với quy trình quản lý từ xa

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
85

tắt máy()

Dừng quá trình được sử dụng bởi người quản lý. Điều này chỉ khả dụng nếu

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
23 đã được sử dụng để bắt đầu quá trình máy chủ

Điều này có thể được gọi nhiều lần

đăng ký(typeid[ , callable[, proxytype[, exposed[, method_to_typeid[, create_method]]]]])

Một phương thức lớp có thể được sử dụng để đăng ký một loại hoặc có thể gọi được với lớp người quản lý

typeid là một "định danh loại" được sử dụng để xác định một loại đối tượng được chia sẻ cụ thể. Đây phải là một chuỗi

có thể gọi được là một có thể gọi được sử dụng để tạo các đối tượng cho loại định danh này. Nếu một phiên bản trình quản lý sẽ được kết nối với máy chủ bằng cách sử dụng phương thức

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
885 hoặc nếu đối số phương thức create_method là
[1, 4, 9]
40 thì điều này có thể được để lại là
[1, 4, 9]
33

proxytype là một lớp con của

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
888 được sử dụng để tạo proxy cho các đối tượng dùng chung với typeid này. Nếu
[1, 4, 9]
33 thì một lớp proxy được tạo tự động

được sử dụng để chỉ định một chuỗi tên phương thức mà proxy cho typeid này sẽ được phép truy cập bằng cách sử dụng

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
890. (Nếu tiếp xúc là
[1, 4, 9]
33 thì
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
892 được sử dụng thay thế nếu nó tồn tại. ) Trong trường hợp không có danh sách hiển thị nào được chỉ định, tất cả các “phương thức công khai” của đối tượng được chia sẻ sẽ có thể truy cập được. (Ở đây “phương thức công khai” có nghĩa là bất kỳ thuộc tính nào có phương thức
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
893 và tên của nó không bắt đầu bằng
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
894. )

method_to_typeid là ánh xạ được sử dụng để chỉ định kiểu trả về của các phương thức được hiển thị đó sẽ trả về proxy. Nó ánh xạ các tên phương thức thành các chuỗi typeid. (Nếu method_to_typeid là

[1, 4, 9]
33 thì
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
896 được sử dụng thay thế nếu nó tồn tại. ) Nếu tên của phương thức không phải là khóa của ánh xạ này hoặc nếu ánh xạ là
[1, 4, 9]
33 thì đối tượng được phương thức trả về sẽ được sao chép theo giá trị

create_method xác định xem một phương thức có nên được tạo với tên typeid có thể được sử dụng để báo cho quy trình máy chủ tạo một đối tượng dùng chung mới và trả về proxy cho nó hay không. Theo mặc định, nó là

[1, 4, 9]
39

Phiên bản

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
899 cũng có một thuộc tính chỉ đọc

địa chỉ

Địa chỉ được sử dụng bởi người quản lý

Đã thay đổi trong phiên bản 3. 3. Các đối tượng trình quản lý hỗ trợ giao thức quản lý ngữ cảnh – xem Các loại trình quản lý ngữ cảnh .

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
950 bắt đầu quá trình máy chủ (nếu nó chưa bắt đầu) và sau đó trả về đối tượng người quản lý.
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
951 cuộc gọi
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
876.

Trong các phiên bản trước,

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
950 đã không bắt đầu quy trình máy chủ của người quản lý nếu nó chưa được bắt đầu

lớp đa xử lý. quản lý. Trình quản lý đồng bộ hóa

Một lớp con của

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
899 có thể được sử dụng để đồng bộ hóa các quy trình. Các đối tượng thuộc loại này được trả về bởi
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
05

Các phương thức của nó tạo và trả về Đối tượng proxy cho một số loại dữ liệu thường được sử dụng để đồng bộ hóa giữa các quy trình. Điều này đáng chú ý bao gồm các danh sách và từ điển được chia sẻ.

Rào cản(các bên[ , action[, timeout]])

Tạo một đối tượng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
958 được chia sẻ và trả về một proxy cho nó

Mới trong phiên bản 3. 3

BoundedSemaphore([giá trị])

Tạo một đối tượng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
959 được chia sẻ và trả về một proxy cho nó

Điều kiện([khóa])

Tạo một đối tượng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
964 được chia sẻ và trả về một proxy cho nó

Nếu lock được cung cấp thì nó phải là proxy cho đối tượng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
970 hoặc
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
991

Changed in version 3. 3. The

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
968 method was added.

Sự kiện()

Tạo một đối tượng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
969 được chia sẻ và trả về một proxy cho nó

Khóa()

Tạo một đối tượng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
970 được chia sẻ và trả về một proxy cho nó

Không gian tên()

Tạo một đối tượng

[1, 4, 9]
14 được chia sẻ và trả về một proxy cho nó

Hàng đợi([kích thước tối đa])

Tạo một đối tượng

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
72 được chia sẻ và trả về một proxy cho nó

RLock()

Tạo một đối tượng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
991 được chia sẻ và trả về một proxy cho nó

Semaphore([giá trị])

Tạo một đối tượng

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
806 được chia sẻ và trả về một proxy cho nó

Mảng(mã loại , trình tự)

Tạo một mảng và trả về một proxy cho nó

Giá trị(mã loại , giá trị)

Tạo một đối tượng có thuộc tính

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
844 có thể ghi và trả về một proxy cho đối tượng đó

dict()dict(mapping)dict(sequence)

Tạo một đối tượng

[1, 4, 9]
13 được chia sẻ và trả về một proxy cho nó

danh sách()danh sách(sequence)

Tạo một đối tượng

[1, 4, 9]
12 được chia sẻ và trả về một proxy cho nó

Đã thay đổi trong phiên bản 3. 6. Các đối tượng được chia sẻ có khả năng được lồng vào nhau. Ví dụ: một đối tượng vùng chứa được chia sẻ, chẳng hạn như danh sách được chia sẻ, có thể chứa các đối tượng được chia sẻ khác, tất cả sẽ được quản lý và đồng bộ hóa bởi

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
863.

lớp đa xử lý. quản lý. Không gian tên

Một loại có thể đăng ký với

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
863

Một đối tượng không gian tên không có phương thức công khai, nhưng có các thuộc tính có thể ghi. Đại diện của nó cho thấy các giá trị của các thuộc tính của nó

Tuy nhiên, khi sử dụng proxy cho đối tượng không gian tên, thuộc tính bắt đầu bằng

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
894 sẽ là thuộc tính của proxy chứ không phải thuộc tính của tham chiếu

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
86

Trình quản lý tùy chỉnh¶

Để tạo trình quản lý của riêng mình, người ta tạo một lớp con của

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
899 và sử dụng phương thức lớp
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
25 để đăng ký các loại hoặc khả năng gọi mới với lớp trình quản lý. Ví dụ

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
87

Sử dụng trình quản lý từ xa¶

Có thể chạy máy chủ quản lý trên một máy và để khách hàng sử dụng nó từ các máy khác (giả sử rằng tường lửa có liên quan cho phép điều đó)

Chạy các lệnh sau sẽ tạo một máy chủ cho một hàng đợi được chia sẻ duy nhất mà các máy khách từ xa có thể truy cập

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
88

Một khách hàng có thể truy cập máy chủ như sau

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
89

Một khách hàng khác cũng có thể sử dụng nó

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
90

Các quy trình cục bộ cũng có thể truy cập hàng đợi đó, sử dụng mã từ phía trên trên máy khách để truy cập từ xa

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
91

Đối tượng ủy nhiệm¶

Proxy là một đối tượng đề cập đến một đối tượng được chia sẻ tồn tại (có lẽ) trong một quy trình khác. Đối tượng được chia sẻ được cho là tham chiếu của proxy. Nhiều đối tượng proxy có thể có cùng một tham chiếu

Một đối tượng proxy có các phương thức gọi các phương thức tương ứng của tham chiếu của nó (mặc dù không phải mọi phương thức của tham chiếu đều nhất thiết phải có sẵn thông qua proxy). Bằng cách này, một proxy có thể được sử dụng giống như người tham chiếu của nó có thể

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
92

Lưu ý rằng việc áp dụng

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
26 cho proxy sẽ trả về biểu diễn của tham chiếu, trong khi áp dụng
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
27 sẽ trả về biểu diễn của proxy

Một tính năng quan trọng của các đối tượng proxy là chúng có thể chọn được để chúng có thể được chuyển giữa các quy trình. Như vậy, một tham chiếu có thể chứa Đối tượng proxy . Điều này cho phép lồng các danh sách được quản lý này, lệnh và các Đối tượng proxy khác.

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
93

Tương tự, proxy dict và list có thể được lồng vào nhau

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
94

Nếu các đối tượng

[1, 4, 9]
12 hoặc
[1, 4, 9]
13 tiêu chuẩn (không phải proxy) được chứa trong một tham chiếu, các sửa đổi đối với các giá trị có thể thay đổi đó sẽ không được truyền qua trình quản lý vì proxy không có cách nào biết khi nào các giá trị chứa trong đó được sửa đổi. Tuy nhiên, việc lưu trữ một giá trị trong proxy vùng chứa (kích hoạt
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
30 trên đối tượng proxy) sẽ truyền qua trình quản lý và do đó, để sửa đổi mục đó một cách hiệu quả, người ta có thể gán lại giá trị đã sửa đổi cho proxy vùng chứa

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
95

Cách tiếp cận này có lẽ kém thuận tiện hơn so với việc sử dụng Đối tượng proxy lồng nhau cho hầu hết các trường hợp sử dụng nhưng cũng thể hiện mức độ kiểm soát đối với quá trình đồng bộ hóa.

Ghi chú

Các loại proxy trong

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6 không làm gì để hỗ trợ so sánh theo giá trị. Vì vậy, ví dụ, chúng ta có

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
96

Thay vào đó, người ta chỉ nên sử dụng một bản sao của người giới thiệu khi so sánh

lớp đa xử lý. quản lý. Proxy cơ sở

Các đối tượng proxy là thể hiện của các lớp con của

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
888

_callmethod(tên phương thức[ , args[, kwds]])

Gọi và trả về kết quả của một phương thức tham chiếu của proxy

Nếu

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
33 là proxy có tham chiếu là
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
34 thì biểu thức

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
97

sẽ đánh giá biểu thức

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
98

trong quy trình của nhà quản lý

Giá trị được trả về sẽ là bản sao kết quả của lệnh gọi hoặc proxy cho một đối tượng được chia sẻ mới – xem tài liệu về đối số method_to_typeid của

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
35

Nếu một ngoại lệ được đưa ra bởi cuộc gọi, thì sẽ được đưa ra lại bởi

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
36. Nếu một số ngoại lệ khác được đưa ra trong quy trình của người quản lý thì điều này được chuyển đổi thành ngoại lệ
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
37 và được đưa ra bởi
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
36

Đặc biệt lưu ý rằng một ngoại lệ sẽ được nêu ra nếu tên phương thức chưa được hiển thị

Một ví dụ về việc sử dụng

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
36

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
99

_getvalue()

Trả lại một bản sao của người giới thiệu

Nếu người giới thiệu không thể chọn được thì điều này sẽ đưa ra một ngoại lệ

__repr__()

Trả về một đại diện của đối tượng proxy

__str__()

Trả về đại diện của tham chiếu

Dọn dẹp¶

Một đối tượng proxy sử dụng một cuộc gọi lại yếu để khi nó được thu gom rác, nó sẽ tự hủy đăng ký khỏi trình quản lý sở hữu tham chiếu của nó

Một đối tượng được chia sẻ sẽ bị xóa khỏi quy trình quản lý khi không còn bất kỳ proxy nào đề cập đến nó

Nhóm quy trình¶

Người ta có thể tạo một nhóm các quy trình sẽ thực hiện các nhiệm vụ được gửi cho nó với lớp

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
5

lớp đa xử lý. hồ bơi. Nhóm([quy trình[, initializer[, initargs[, maxtasksperchild[, context]]]]])

Một đối tượng nhóm quy trình kiểm soát nhóm quy trình công nhân mà công việc có thể được gửi tới. Nó hỗ trợ các kết quả không đồng bộ với thời gian chờ và gọi lại và có triển khai bản đồ song song

quy trình là số lượng quy trình công nhân để sử dụng. Nếu các quy trình là

[1, 4, 9]
33 thì số được trả về bởi
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
879 được sử dụng

Nếu trình khởi tạo không phải là

[1, 4, 9]
33 thì mỗi worker process sẽ gọi
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
878 khi nó bắt đầu

maxtasksperchild là số lượng tác vụ mà một worker process có thể hoàn thành trước khi nó thoát và được thay thế bằng một worker process mới, để cho phép giải phóng các tài nguyên không sử dụng. Maxtaskperchild mặc định là

[1, 4, 9]
33, có nghĩa là worker process sẽ tồn tại miễn là pool

bối cảnh có thể được sử dụng để chỉ định bối cảnh được sử dụng để bắt đầu các quy trình worker. Thông thường, một nhóm được tạo bằng cách sử dụng hàm

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
46 hoặc phương thức
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
47 của một đối tượng bối cảnh. Trong cả hai trường hợp bối cảnh được thiết lập một cách thích hợp

Lưu ý rằng các phương thức của đối tượng nhóm chỉ nên được gọi bởi quá trình tạo nhóm

Cảnh báo

Các đối tượng

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
48 có tài nguyên nội bộ cần được quản lý đúng cách (giống như bất kỳ tài nguyên nào khác) bằng cách sử dụng nhóm làm trình quản lý bối cảnh hoặc bằng cách gọi thủ công
[1, 4, 9]
75 và
[1, 4, 9]
71. Không làm điều này có thể dẫn đến quá trình bị treo khi quyết toán

Lưu ý rằng việc dựa vào trình thu gom rác để hủy nhóm là không đúng vì CPython không đảm bảo rằng trình hoàn thiện của nhóm sẽ được gọi (xem

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
51 để biết thêm thông tin)

Mới trong phiên bản 3. 2. maxtaskperchild

Mới trong phiên bản 3. 4. bối cảnh

Ghi chú

Các quy trình công nhân trong một

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
5 thường tồn tại trong toàn bộ thời lượng của hàng đợi công việc của Nhóm. Một mô hình phổ biến được tìm thấy trong các hệ thống khác (chẳng hạn như Apache, mod_wsgi, v.v.) để giải phóng tài nguyên do công nhân nắm giữ là cho phép một công nhân trong nhóm chỉ hoàn thành một lượng công việc nhất định trước khi thoát, được dọn sạch và một quy trình mới được sinh ra . Đối số maxtasksperchild cho
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
5 hiển thị khả năng này cho người dùng cuối

áp dụng(chức năng[ , args[, kwds]])

Gọi func với đối số args và đối số từ khóa kwds. Nó chặn cho đến khi kết quả sẵn sàng. Với các khối này,

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
54 phù hợp hơn để thực hiện công việc song song. Ngoài ra, func chỉ được thực thi ở một trong các công nhân của nhóm

apply_async(func[ , args[, kwds[, callback[, error_callback]]]])

Một biến thể của phương thức

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
55 trả về một đối tượng
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
56

Nếu gọi lại được chỉ định thì nó phải là một cuộc gọi có thể chấp nhận một đối số. Khi kết quả sẵn sàng gọi lại được áp dụng cho nó, đó là trừ khi cuộc gọi không thành công, trong trường hợp đó, error_callback được áp dụng thay thế

Nếu error_callback được chỉ định thì nó phải là một đối số có thể gọi được chấp nhận một đối số. Nếu chức năng đích không thành công, thì error_callback được gọi với trường hợp ngoại lệ

Các cuộc gọi lại phải hoàn thành ngay lập tức vì nếu không thì chuỗi xử lý kết quả sẽ bị chặn

map(func , có thể lặp lại[, chunksize])

Tương đương song song với chức năng tích hợp sẵn của

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
57 (tuy nhiên, nó chỉ hỗ trợ một đối số có thể lặp lại, đối với nhiều lần lặp lại, hãy xem
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
58). Nó chặn cho đến khi kết quả sẵn sàng

Phương pháp này cắt iterable thành một số khối mà nó gửi đến nhóm quy trình dưới dạng các tác vụ riêng biệt. Kích thước (gần đúng) của các khối này có thể được chỉ định bằng cách đặt kích thước khối thành một số nguyên dương

Lưu ý rằng nó có thể gây ra việc sử dụng bộ nhớ cao cho các lần lặp rất dài. Cân nhắc sử dụng

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
59 hoặc
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
60 với tùy chọn chunksize rõ ràng để có hiệu quả tốt hơn

map_async(func , có thể lặp lại[, chunksize[, callback[, error_callback]]])

Một biến thể của phương thức

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
57 trả về một đối tượng
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
56

Nếu gọi lại được chỉ định thì nó phải là một cuộc gọi có thể chấp nhận một đối số. Khi kết quả sẵn sàng gọi lại được áp dụng cho nó, đó là trừ khi cuộc gọi không thành công, trong trường hợp đó, error_callback được áp dụng thay thế

Nếu error_callback được chỉ định thì nó phải là một đối số có thể gọi được chấp nhận một đối số. Nếu chức năng đích không thành công, thì error_callback được gọi với trường hợp ngoại lệ

Các cuộc gọi lại phải hoàn thành ngay lập tức vì nếu không thì chuỗi xử lý kết quả sẽ bị chặn

imap(func , có thể lặp lại[, chunksize])

Phiên bản lười biếng hơn của

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
57

Đối số chunksize giống như đối số được sử dụng bởi phương thức

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
57. Đối với các lần lặp rất dài, sử dụng giá trị lớn cho chunksize có thể giúp công việc hoàn thành nhanh hơn nhiều so với sử dụng giá trị mặc định là
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
65

Ngoài ra, nếu chunksize là

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
65 thì phương thức
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
67 của trình vòng lặp được trả về bởi phương thức
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
59 có tham số thời gian chờ tùy chọn.
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
69 sẽ tăng
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
70 nếu kết quả không thể trả về trong thời gian chờ vài giây

imap_unordered(func , có thể lặp lại[, chunksize])

Giống như

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
59 ngoại trừ thứ tự của kết quả từ trình lặp được trả về nên được coi là tùy ý. (Chỉ khi chỉ có một worker process thì lệnh mới được đảm bảo là “đúng”. )

starmap(func , có thể lặp lại[, chunksize])

Giống như

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
57 ngoại trừ các phần tử của iterable dự kiến ​​​​là iterables được giải nén dưới dạng đối số

Do đó, một lần lặp lại của

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
73 dẫn đến
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
74

Mới trong phiên bản 3. 3

starmap_async(func , có thể lặp lại[, chunksize[, callback[, error_callback]]])

Một sự kết hợp của

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
58 và
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
76 lặp đi lặp lại trên iterable của iterables và gọi func với iterables được giải nén. Trả về một đối tượng kết quả

Mới trong phiên bản 3. 3

đóng()

Ngăn chặn bất kỳ nhiệm vụ nào khác được gửi đến nhóm. Khi tất cả các tác vụ đã được hoàn thành, các quy trình công nhân sẽ thoát

chấm dứt()

Dừng quy trình công nhân ngay lập tức mà không hoàn thành công việc chưa hoàn thành. Khi đối tượng pool được thu gom rác,

[1, 4, 9]
71 sẽ được gọi ngay lập tức

tham gia()

Chờ các worker process thoát ra. Người ta phải gọi

[1, 4, 9]
75 hoặc
[1, 4, 9]
71 trước khi sử dụng
[1, 4, 9]
48

Mới trong phiên bản 3. 3. Các đối tượng nhóm hiện hỗ trợ giao thức quản lý bối cảnh – xem Các loại trình quản lý bối cảnh .

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
950 trả về đối tượng pool và
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
951 gọi
[1, 4, 9]
71.

lớp đa xử lý. hồ bơi. Kết quả không đồng bộ

Lớp của kết quả được trả về bởi

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
84 và
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
85

nhận([thời gian chờ])

Trả lại kết quả khi nó đến. Nếu thời gian chờ không phải là

[1, 4, 9]
33 và kết quả không đến trong vòng vài giây hết thời gian chờ thì
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
70 được nâng lên. Nếu cuộc gọi từ xa đưa ra một ngoại lệ thì ngoại lệ đó sẽ được đưa ra lại trước
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
860

chờ([hết giờ])

Đợi cho đến khi có kết quả hoặc cho đến khi hết giây

sẵn sàng()

Quay lại xem cuộc gọi đã hoàn thành chưa

thành công()

Trả lại xem cuộc gọi có hoàn thành mà không đưa ra ngoại lệ hay không. Sẽ tăng

[1, 4, 9]
74 nếu kết quả chưa sẵn sàng

Đã thay đổi trong phiên bản 3. 7. Nếu kết quả chưa sẵn sàng,

[1, 4, 9]
74 được nâng lên thay vì
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
838.

Ví dụ sau minh họa việc sử dụng pool

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
80

Người nghe và Khách hàng¶

Thông thường việc chuyển thông báo giữa các quy trình được thực hiện bằng cách sử dụng hàng đợi hoặc bằng cách sử dụng các đối tượng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
814 được trả về bởi
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
73

Tuy nhiên, mô-đun

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
94 cho phép linh hoạt hơn. Về cơ bản, nó cung cấp API định hướng thông báo cấp cao để xử lý các ổ cắm hoặc đường ống có tên Windows. Nó cũng có hỗ trợ xác thực thông báo bằng cách sử dụng mô-đun
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
95 và để thăm dò nhiều kết nối cùng một lúc

đa xử lý. sự liên quan. deliver_challenge(kết nối , mã xác thực)

Gửi một tin nhắn được tạo ngẫu nhiên đến đầu kia của kết nối và chờ phản hồi

Nếu câu trả lời khớp với thông báo của tin nhắn sử dụng authkey làm khóa thì tin nhắn chào mừng sẽ được gửi đến đầu kia của kết nối. Nếu không thì

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
96 được nâng lên

đa xử lý. sự liên quan. answer_challenge(kết nối , mã xác thực)

Nhận một tin nhắn, tính toán thông báo của tin nhắn bằng authkey làm khóa, sau đó gửi lại thông báo

Nếu không nhận được tin nhắn chào mừng, thì

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
96 được nâng lên

đa xử lý. sự liên quan. Khách hàng(địa chỉ[ , family[, authkey]])

Cố gắng thiết lập kết nối với người nghe đang sử dụng địa chỉ address, trả về

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
814

Loại kết nối được xác định bởi đối số họ, nhưng điều này thường có thể được bỏ qua vì nó thường có thể được suy ra từ định dạng địa chỉ. (Xem Định dạng địa chỉ )

Nếu authkey được cung cấp và không phải là Không có, thì đó phải là một chuỗi byte và sẽ được sử dụng làm khóa bí mật cho thử thách xác thực dựa trên HMAC. Không có xác thực nào được thực hiện nếu authkey là Không có.

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
96 được nâng lên nếu xác thực không thành công. Xem Khóa xác thực .

lớp đa xử lý. sự liên quan. Người nghe([địa chỉ[, family[, backlog[, authkey]]]])

Trình bao bọc cho ổ cắm bị ràng buộc hoặc đường ống có tên Windows đang 'lắng nghe' các kết nối

địa chỉ là địa chỉ được sử dụng bởi ổ cắm bị ràng buộc hoặc đường ống có tên của đối tượng người nghe

Ghi chú

Nếu một địa chỉ của '0. 0. 0. 0' được sử dụng, địa chỉ sẽ không phải là điểm cuối có thể kết nối trên Windows. Nếu bạn yêu cầu điểm cuối có thể kết nối, bạn nên sử dụng '127. 0. 0. 1’

họ là loại ổ cắm (hoặc ống có tên) sẽ sử dụng. Đây có thể là một trong các chuỗi

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
00 (đối với ổ cắm TCP),
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
01 (đối với ổ cắm tên miền Unix) hoặc
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
02 (đối với đường ống có tên Windows). Trong số này chỉ có cái đầu tiên được đảm bảo có sẵn. Nếu gia đình là
[1, 4, 9]
33 thì gia đình được suy ra từ định dạng địa chỉ. Nếu địa chỉ cũng là
[1, 4, 9]
33 thì giá trị mặc định được chọn. Mặc định này là họ được coi là nhanh nhất hiện có. Xem Định dạng địa chỉ . Lưu ý rằng nếu họ là
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
01 và địa chỉ là
[1, 4, 9]
33 thì ổ cắm sẽ được tạo trong một thư mục tạm thời riêng được tạo bằng cách sử dụng
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
07.

Nếu đối tượng người nghe sử dụng ổ cắm thì tồn đọng (1 theo mặc định) được chuyển đến phương thức

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
08 của ổ cắm sau khi nó đã được liên kết

Nếu authkey được cung cấp và không phải là Không có, thì đó phải là một chuỗi byte và sẽ được sử dụng làm khóa bí mật cho thử thách xác thực dựa trên HMAC. Không có xác thực nào được thực hiện nếu authkey là Không có.

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
96 được nâng lên nếu xác thực không thành công. Xem Khóa xác thực .

chấp nhận()

Chấp nhận kết nối trên ổ cắm bị ràng buộc hoặc đường ống có tên của đối tượng người nghe và trả về đối tượng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
814. Nếu xác thực được thử và không thành công, thì
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
96 sẽ được nâng lên

đóng()

Đóng ổ cắm bị ràng buộc hoặc đường ống có tên của đối tượng người nghe. Điều này được gọi tự động khi người nghe được thu gom rác. Tuy nhiên, nên gọi nó một cách rõ ràng

Các đối tượng người nghe có các thuộc tính chỉ đọc sau

địa chỉ

Địa chỉ đang được sử dụng bởi đối tượng Listener

last_accepted

Địa chỉ mà từ đó kết nối được chấp nhận cuối cùng đến. Nếu cái này không khả dụng thì đó là

[1, 4, 9]
33

Mới trong phiên bản 3. 3. Các đối tượng trình nghe hiện hỗ trợ giao thức quản lý bối cảnh – xem Các loại trình quản lý bối cảnh .

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
950 trả về đối tượng người nghe và
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
951 gọi
[1, 4, 9]
75.

đa xử lý. sự liên quan. chờ đã(object_list , hết thời gian=None)

Đợi cho đến khi một đối tượng trong object_list sẵn sàng. Trả về danh sách các đối tượng đó trong object_list đã sẵn sàng. Nếu thời gian chờ là thời gian trôi nổi thì cuộc gọi sẽ chặn nhiều nhất là bao nhiêu giây. Nếu thời gian chờ là

[1, 4, 9]
33 thì nó sẽ bị chặn trong một khoảng thời gian không giới hạn. Thời gian chờ âm tương đương với thời gian chờ bằng 0

Đối với cả Unix và Windows, một đối tượng có thể xuất hiện trong object_list nếu nó

  • một đối tượng

    class GizmoAccountingSystem(AccountingSystem):
    
        def create_purchase_invoice(self, purchase):
            submit_to_gizmo_purchase_service(purchase)
    
        def create_sale_invoice(self, sale):
            super().create_sale_invoice(sale)
            submit_to_gizmo_sale_service(sale)
    
    814 có thể đọc được;

  • một đối tượng

    from multiprocessing import Process, Queue
    
    def f(q):
        q.put([42, None, 'hello'])
    
    if __name__ == '__main__':
        q = Queue()
        p = Process(target=f, args=(q,))
        p.start()
        print(q.get())    # prints "[42, None, 'hello']"
        p.join()
    
    18 được kết nối và có thể đọc được;

  • thuộc tính

    from multiprocessing import Process, Queue
    
    def f(q):
        q.put([42, None, 'hello'])
    
    if __name__ == '__main__':
        q = Queue()
        p = Process(target=f, args=(q,))
        p.start()
        print(q.get())    # prints "[42, None, 'hello']"
        p.join()
    
    19 của đối tượng
    class GizmoAccountingSystem(AccountingSystem):
    
        def create_purchase_invoice(self, purchase):
            submit_to_gizmo_purchase_service(purchase)
    
        def create_sale_invoice(self, sale):
            super().create_sale_invoice(sale)
            submit_to_gizmo_sale_service(sale)
    
    20

Một đối tượng kết nối hoặc ổ cắm đã sẵn sàng khi có sẵn dữ liệu để đọc từ nó hoặc đầu kia đã bị đóng

Unix.

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
21 gần như tương đương
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
22. Sự khác biệt là, nếu
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
23 bị gián đoạn bởi tín hiệu, nó có thể tăng
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
846 với số lỗi là
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
25, trong khi
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
26 thì không

các cửa sổ. Một mục trong object_list phải là một số nguyên xử lý có thể chờ được (theo định nghĩa được sử dụng bởi tài liệu về hàm Win32 ________ _ _ _ _ _ _ _ _ _ _ Nó có thể là một đối tượng có phương thức ____________ trả về một tay cầm ổ cắm hoặc tay cầm ống. (Lưu ý rằng tay cầm ống và tay cầm ổ cắm không phải là tay cầm có thể chờ được. )

Mới trong phiên bản 3. 3

ví dụ

Mã máy chủ sau đây tạo một trình lắng nghe sử dụng

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
29 làm khóa xác thực. Sau đó, nó chờ kết nối và gửi một số dữ liệu đến máy khách

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
81

Đoạn mã sau kết nối với máy chủ và nhận một số dữ liệu từ máy chủ

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
82

Đoạn mã sau sử dụng

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
26 để đợi tin nhắn từ nhiều quy trình cùng một lúc

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
83

Định dạng địa chỉ¶

  • Địa chỉ

    from multiprocessing import Process, Queue
    
    def f(q):
        q.put([42, None, 'hello'])
    
    if __name__ == '__main__':
        q = Queue()
        p = Process(target=f, args=(q,))
        p.start()
        print(q.get())    # prints "[42, None, 'hello']"
        p.join()
    
    00 là một bộ có dạng
    from multiprocessing import Process, Queue
    
    def f(q):
        q.put([42, None, 'hello'])
    
    if __name__ == '__main__':
        q = Queue()
        p = Process(target=f, args=(q,))
        p.start()
        print(q.get())    # prints "[42, None, 'hello']"
        p.join()
    
    32 trong đó tên máy chủ là một chuỗi và cổng là một số nguyên

  • Địa chỉ

    from multiprocessing import Process, Queue
    
    def f(q):
        q.put([42, None, 'hello'])
    
    if __name__ == '__main__':
        q = Queue()
        p = Process(target=f, args=(q,))
        p.start()
        print(q.get())    # prints "[42, None, 'hello']"
        p.join()
    
    01 là một chuỗi đại diện cho tên tệp trên hệ thống tệp

  • Địa chỉ

    from multiprocessing import Process, Queue
    
    def f(q):
        q.put([42, None, 'hello'])
    
    if __name__ == '__main__':
        q = Queue()
        p = Process(target=f, args=(q,))
        p.start()
        print(q.get())    # prints "[42, None, 'hello']"
        p.join()
    
    02 là một chuỗi có dạng
    from multiprocessing import Process, Queue
    
    def f(q):
        q.put([42, None, 'hello'])
    
    if __name__ == '__main__':
        q = Queue()
        p = Process(target=f, args=(q,))
        p.start()
        print(q.get())    # prints "[42, None, 'hello']"
        p.join()
    
    35. Để sử dụng
    from multiprocessing import Process, Queue
    
    def f(q):
        q.put([42, None, 'hello'])
    
    if __name__ == '__main__':
        q = Queue()
        p = Process(target=f, args=(q,))
        p.start()
        print(q.get())    # prints "[42, None, 'hello']"
        p.join()
    
    36 để kết nối với một đường ống có tên trên máy tính từ xa có tên ServerName, thay vào đó, bạn nên sử dụng một địa chỉ có dạng
    from multiprocessing import Process, Queue
    
    def f(q):
        q.put([42, None, 'hello'])
    
    if __name__ == '__main__':
        q = Queue()
        p = Process(target=f, args=(q,))
        p.start()
        print(q.get())    # prints "[42, None, 'hello']"
        p.join()
    
    37

Lưu ý rằng bất kỳ chuỗi nào bắt đầu bằng hai dấu gạch chéo ngược đều được mặc định là địa chỉ

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
02 thay vì địa chỉ
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
01

Khóa xác thực¶

Khi một người sử dụng

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
40, dữ liệu nhận được sẽ tự động được giải nén. Thật không may, việc giải nén dữ liệu từ một nguồn không đáng tin cậy là một rủi ro bảo mật. Do đó,
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
41 và
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
36 sử dụng mô-đun
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
95 để cung cấp xác thực thông báo

Khóa xác thực là một chuỗi byte có thể được coi là mật khẩu. khi kết nối được thiết lập, cả hai đầu sẽ yêu cầu bằng chứng rằng đầu kia biết khóa xác thực. (Chứng minh rằng cả hai đầu đang sử dụng cùng một khóa không liên quan đến việc gửi khóa qua kết nối. )

Nếu xác thực được yêu cầu nhưng không có khóa xác thực nào được chỉ định thì giá trị trả về của

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
869 sẽ được sử dụng (xem
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
20). Giá trị này sẽ được tự động kế thừa bởi bất kỳ đối tượng
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
20 nào mà quy trình hiện tại tạo ra. Điều này có nghĩa là (theo mặc định) tất cả các quy trình của chương trình đa quy trình sẽ chia sẻ một khóa xác thực duy nhất có thể được sử dụng khi thiết lập kết nối giữa chúng

Các khóa xác thực phù hợp cũng có thể được tạo bằng cách sử dụng

[1, 4, 9]
61

Ghi nhật ký¶

Một số hỗ trợ cho ghi nhật ký có sẵn. Tuy nhiên, lưu ý rằng gói

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
48 không sử dụng khóa chia sẻ quy trình nên có thể (tùy thuộc vào loại trình xử lý) cho các thông báo từ các quy trình khác nhau bị lẫn lộn

đa xử lý. get_logger()

Trả về nhật ký được sử dụng bởi

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6. Nếu cần thiết, một cái mới sẽ được tạo ra

Khi được tạo lần đầu tiên, bộ ghi có cấp độ

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
50 và không có trình xử lý mặc định. Theo mặc định, các tin nhắn được gửi tới bộ ghi này sẽ không lan truyền tới bộ ghi gốc

Lưu ý rằng trên Windows, các tiến trình con sẽ chỉ kế thừa cấp độ của trình ghi nhật ký của tiến trình cha – bất kỳ tùy chỉnh nào khác của trình ghi nhật ký sẽ không được kế thừa

đa xử lý. log_to_stderr(cấp độ=Không có)

Hàm này thực hiện lệnh gọi tới

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
51 nhưng ngoài việc trả về trình ghi nhật ký được tạo bởi get_logger, nó còn thêm một trình xử lý gửi đầu ra tới
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
52 bằng định dạng
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
53. Bạn có thể sửa đổi
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
54 của bộ ghi nhật ký bằng cách chuyển đối số
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
55

Dưới đây là phiên ví dụ có bật ghi nhật ký

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
84

Để biết bảng đầy đủ các cấp độ ghi nhật ký, hãy xem mô-đun

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
48

Mô-đun from multiprocessing import Process, Queue def f(q): q.put([42, None, 'hello']) if __name__ == '__main__': q = Queue() p = Process(target=f, args=(q,)) p.start() print(q.get()) # prints "[42, None, 'hello']" p.join() 57¶

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
57 sao chép API của
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6 nhưng không hơn gì một trình bao bọc xung quanh mô-đun
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
0

Cụ thể, hàm

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
5 do
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
57 cung cấp trả về một thể hiện của
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
63, là một lớp con của
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
5 hỗ trợ tất cả các lời gọi phương thức giống nhau nhưng sử dụng một nhóm các chuỗi công nhân thay vì các quy trình công nhân

lớp đa xử lý. hồ bơi. ThreadPool([quy trình[, initializer[, initargs]]])

Một đối tượng nhóm luồng kiểm soát nhóm luồng công nhân mà công việc có thể được gửi tới. Các phiên bản

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
63 hoàn toàn có giao diện tương thích với các phiên bản
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
5 và tài nguyên của chúng cũng phải được quản lý đúng cách, bằng cách sử dụng nhóm làm trình quản lý bối cảnh hoặc bằng cách gọi thủ công
[1, 4, 9]
75 và
[1, 4, 9]
71

quy trình là số lượng luồng công nhân sẽ sử dụng. Nếu các quy trình là

[1, 4, 9]
33 thì số được trả về bởi
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
879 được sử dụng

Nếu trình khởi tạo không phải là

[1, 4, 9]
33 thì mỗi worker process sẽ gọi
class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
878 khi nó bắt đầu

Không giống như

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
5, không thể cung cấp maxt taskperchild và bối cảnh

Ghi chú

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
63 chia sẻ giao diện giống như
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
5, được thiết kế xung quanh một nhóm các quy trình và có trước khi giới thiệu mô-đun
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
9. Do đó, nó kế thừa một số thao tác không có ý nghĩa đối với một nhóm được hỗ trợ bởi các luồng và nó có loại riêng để biểu thị trạng thái của các công việc không đồng bộ,
import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
56, mà bất kỳ thư viện nào khác không hiểu được

Người dùng nói chung nên sử dụng

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
78, có giao diện đơn giản hơn được thiết kế xung quanh các luồng ngay từ đầu và trả về các phiên bản
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
79 tương thích với nhiều thư viện khác, bao gồm cả
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
80

Hướng dẫn lập trình¶

Có một số nguyên tắc và thành ngữ cần được tuân thủ khi sử dụng

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6

Tất cả các phương pháp bắt đầu¶

Những điều sau đây áp dụng cho tất cả các phương pháp bắt đầu

Tránh trạng thái chia sẻ

Càng nhiều càng tốt, người ta nên cố gắng tránh chuyển một lượng lớn dữ liệu giữa các quy trình

Có lẽ tốt nhất là nên sử dụng hàng đợi hoặc đường ống để liên lạc giữa các quy trình thay vì sử dụng các nguyên mẫu đồng bộ hóa cấp thấp hơn

độ chua

Đảm bảo rằng các đối số cho các phương thức của proxy có thể chọn được

Chủ đề an toàn của proxy

Không sử dụng đối tượng proxy từ nhiều luồng trừ khi bạn bảo vệ nó bằng khóa

(Không bao giờ có vấn đề với các quy trình khác nhau sử dụng cùng một proxy. )

Tham gia các quá trình zombie

Trên Unix khi một quá trình kết thúc nhưng chưa được kết nối, nó sẽ trở thành một thây ma. Không bao giờ nên có quá nhiều vì mỗi khi một quy trình mới bắt đầu (hoặc gọi là

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
82) thì tất cả các quy trình đã hoàn thành chưa được tham gia sẽ được tham gia. Đồng thời gọi một quy trình đã hoàn thành là
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
83 sẽ tham gia quy trình. Mặc dù vậy, có lẽ nên tham gia một cách rõ ràng tất cả các quy trình mà bạn bắt đầu

Kế thừa tốt hơn là dưa chua/bỏ dưa chua

Khi sử dụng các phương thức khởi động spawn hoặc forkserver, nhiều loại từ

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6 cần phải được chọn để các tiến trình con có thể sử dụng chúng. Tuy nhiên, người ta thường tránh gửi các đối tượng được chia sẻ đến các quy trình khác bằng cách sử dụng đường ống hoặc hàng đợi. Thay vào đó, bạn nên sắp xếp chương trình sao cho một quy trình cần truy cập vào tài nguyên được chia sẻ được tạo ở nơi khác có thể kế thừa nó từ quy trình tổ tiên

Tránh chấm dứt quá trình

Việc sử dụng phương pháp

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
85 để dừng một quy trình có thể khiến bất kỳ tài nguyên dùng chung nào (chẳng hạn như khóa, semaphores, đường ống và hàng đợi) hiện đang được quy trình sử dụng bị hỏng hoặc không khả dụng đối với các quy trình khác

Do đó, có lẽ tốt nhất là chỉ xem xét sử dụng

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
85 trên các quy trình không bao giờ sử dụng bất kỳ tài nguyên được chia sẻ nào

Tham gia các quy trình sử dụng hàng đợi

Hãy nhớ rằng một quy trình đã đặt các mục vào hàng đợi sẽ đợi trước khi kết thúc cho đến khi tất cả các mục được lưu trong bộ đệm được luồng "bộ nạp" nạp vào đường ống bên dưới. (Tiến trình con có thể gọi phương thức

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
87 của hàng đợi để tránh hành vi này. )

Điều này có nghĩa là bất cứ khi nào bạn sử dụng hàng đợi, bạn cần đảm bảo rằng tất cả các mục đã được đưa vào hàng đợi cuối cùng sẽ bị xóa trước khi quy trình được tham gia. Nếu không, bạn không thể chắc chắn rằng các quy trình đã đặt các mục vào hàng đợi sẽ kết thúc. Cũng nên nhớ rằng các quy trình không phải daemon sẽ được tự động tham gia

Một ví dụ sẽ bế tắc như sau

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
85

Cách khắc phục ở đây là hoán đổi hai dòng cuối cùng (hoặc chỉ cần xóa dòng

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
88)

Truyền rõ ràng tài nguyên cho các tiến trình con

Trên Unix sử dụng phương thức fork start, một tiến trình con có thể sử dụng tài nguyên được chia sẻ được tạo trong tiến trình cha bằng tài nguyên chung. Tuy nhiên, tốt hơn là truyền đối tượng làm đối số cho hàm tạo cho tiến trình con

Ngoài việc làm cho mã (có khả năng) tương thích với Windows và các phương thức bắt đầu khác, điều này còn đảm bảo rằng miễn là tiến trình con vẫn còn hoạt động, đối tượng sẽ không bị thu gom rác trong tiến trình cha. Điều này có thể quan trọng nếu một số tài nguyên được giải phóng khi đối tượng được thu gom rác trong quy trình gốc

Vì vậy, ví dụ

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
86

nên được viết lại như

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
87

Cẩn thận khi thay thế

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
89 bằng một “tệp giống như đối tượng”

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
6 ban đầu được gọi vô điều kiện

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
88

trong phương pháp

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
91 - điều này dẫn đến các vấn đề với quy trình đang xử lý. Điều này đã được thay đổi thành

class IncompleteAccountingSystem(AccountingSystem):
    pass

>>> accounting = IncompleteAccountingSystem()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: Can't instantiate abstract class IncompleteAccountingSystem with abstract methods
create_purchase_invoice, create_sale_invoice
89

Điều này giải quyết vấn đề cơ bản của các quy trình va chạm với nhau dẫn đến lỗi bộ mô tả tệp không hợp lệ, nhưng lại gây ra mối nguy hiểm tiềm tàng cho các ứng dụng thay thế

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
92 bằng một “đối tượng giống như tệp” với bộ đệm đầu ra. Mối nguy hiểm này là nếu nhiều quy trình gọi
[1, 4, 9]
75 trên đối tượng giống như tệp này, nó có thể dẫn đến việc cùng một dữ liệu được chuyển sang đối tượng nhiều lần, dẫn đến hỏng

Nếu bạn viết một đối tượng giống như tệp và triển khai bộ nhớ đệm của riêng mình, bạn có thể làm cho nó an toàn bằng cách lưu trữ pid bất cứ khi nào bạn thêm vào bộ đệm và loại bỏ bộ đệm khi pid thay đổi. Ví dụ

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
0

Để biết thêm thông tin, hãy xem bpo-5155, bpo-5313 và bpo-5331

Các phương thức bắt đầu spawn và forkserver¶

Có một số hạn chế bổ sung không áp dụng cho phương thức khởi động fork

dễ ăn hơn

Đảm bảo rằng tất cả các đối số của

[1, 4, 9]
43 đều có thể chọn được. Ngoài ra, nếu bạn phân lớp
class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
20 thì hãy đảm bảo rằng các phiên bản đó sẽ có thể chọn được khi phương thức
from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
96 được gọi

biến toàn cầu

Hãy nhớ rằng nếu mã chạy trong một tiến trình con cố gắng truy cập vào một biến toàn cục, thì giá trị mà nó thấy (nếu có) có thể không giống với giá trị trong tiến trình mẹ tại thời điểm mà

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
96 được gọi

Tuy nhiên, các biến toàn cục chỉ là hằng số cấp độ mô-đun không gây ra vấn đề gì

Nhập an toàn mô-đun chính

Đảm bảo rằng mô-đun chính có thể được nhập an toàn bởi trình thông dịch Python mới mà không gây ra tác dụng phụ ngoài ý muốn (chẳng hạn như bắt đầu một quy trình mới)

Ví dụ: sử dụng phương thức khởi động spawn hoặc forkserver chạy mô-đun sau sẽ không thành công với

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
889

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
1

Thay vào đó, người ta nên bảo vệ “điểm vào” của chương trình bằng cách sử dụng

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
99 như sau

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
2

(Có thể bỏ dòng

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
888 nếu chương trình sẽ chạy bình thường thay vì đóng băng. )

Điều này cho phép trình thông dịch Python mới được tạo ra nhập mô-đun một cách an toàn và sau đó chạy hàm

class GizmoAccountingSystem(AccountingSystem):

    def create_purchase_invoice(self, purchase):
        submit_to_gizmo_purchase_service(purchase)

    def create_sale_invoice(self, sale):
        super().create_sale_invoice(sale)
        submit_to_gizmo_sale_service(sale)
201 của mô-đun

Áp dụng các hạn chế tương tự nếu một nhóm hoặc trình quản lý được tạo trong mô-đun chính

Ví dụ¶

Trình diễn cách tạo và sử dụng trình quản lý và proxy tùy chỉnh

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
3

Sử dụng

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print(q.get())    # prints "[42, None, 'hello']"
    p.join()
5

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    ctx = mp.get_context('spawn')
    q = ctx.Queue()
    p = ctx.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
4

Một ví dụ cho thấy cách sử dụng hàng đợi để cung cấp các tác vụ cho một tập hợp các quy trình công nhân và thu thập kết quả

Giao diện chức năng Python là gì?

Giao diện của hàm là bản tóm tắt về cách sử dụng hàm . các thông số là gì? . (

Giao diện LÀ GÌ và chức năng của nó?

Giao diện là mô tả các hành động mà một đối tượng có thể thực hiện . ví dụ khi bạn bật công tắc đèn, đèn sáng, bạn không quan tâm làm thế nào, chỉ cần nó sáng. Trong Lập trình hướng đối tượng, Giao diện là mô tả tất cả các chức năng mà một đối tượng phải có để trở thành "X".

Các giao diện khác nhau của Python là gì?

Thật không may, Python không có giao diện, hoặc ít nhất, không được tích hợp hoàn toàn vào ngôn ngữ. Nhập lớp cơ sở trừu tượng của Python, hoặc dễ thương là ABC. Về mặt chức năng, các lớp cơ sở trừu tượng cho phép bạn định nghĩa một lớp với các phương thức trừu tượng mà tất cả các lớp con phải triển khai để được khởi tạo

Làm thế nào để thiết kế giao diện bằng Python?

Cách xây dựng ứng dụng GUI Python với wxPython .
Bắt đầu với wxPython. Cài đặt wxPython. Định nghĩa về GUI. Vòng lặp sự kiện
Tạo một ứng dụng Skeleton. tiện ích. định vị tuyệt đối. .
Tạo một ứng dụng làm việc. Thiết kế giao diện người dùng. Tạo giao diện người dùng. .
Phần kết luận
Đọc thêm