Python song song cho ví dụ đa xử lý vòng lặp

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 này về tính 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

[1, 4, 9]

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
from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]

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
from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
0 và sau đó gọi phương thức
from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
3 của nó.
from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
0 tuân theo API của
from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
5. Một ví dụ nhỏ về chương trình đa xử lý 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[]
5

Để 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

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[]
6

Để biết giải thích về lý do tại sao phần

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
6 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 một quy trình. Các phương thức bắt đầu này là

spawn

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

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
8 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

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
9 để 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ủ fork là một luồng đơn nên sẽ an toàn khi sử dụng

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
9. Không có tài nguyên không cần thiết được kế thừa

Available on Unix platforms which support passing file descriptors over Unix pipes

Đã 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. spawn added on all Unix platforms, and forkserver added for some Unix platforms. Child processes no longer inherit all of the parents inheritable handles on Windows.

Trên Unix, việc sử dụng các phương thức khởi động spawn hoặc forkserver cũng sẽ bắt đầu một 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ư các semaphores được đặt tên hoặc các đố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[]
21] đượ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

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 trong mệnh đề
from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
6 của mô-đun chính. For example

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 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 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

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 để 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. In particular, locks created using the fork context cannot be passed to processes started using the spawn or forkserver start methods

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

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 để tránh ảnh hưởng đến sự lựa chọn của người dùng thư viện

Cảnh báo

The

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[]
27 and
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[]
28 start methods cannot currently be used with “frozen” executables [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
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 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

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 gần như là bản sao của 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[]
42. 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

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[]
43 trả về một cặp đối tượng kết nối được kết nối bằng một đường ống mà theo mặc định là song công [hai chiều]. Ví dụ

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]

Hai đối tượng kết nối được trả về bở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[]
43 đạ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
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[]
45 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[]
46 [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. Of course there is no risk of corruption from processes using different ends of the pipe at the same time

Đồ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. For instance one can use a lock to ensure that only one process prints to standard output at a time

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[]
2

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. This is particularly true when using multiple processes

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

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[]
4

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 cấp phát 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 điều khiển 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

A manager returned by

[1, 4, 9]
10 will support types
[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,
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,
[1, 4, 9]
00 and
[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

[If you try this it will actually output three full tracebacks interleaved in a semi-random fashion, and then you may have to stop the parent process somehow. ]

Reference¶

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

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
0 và các trường hợp 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

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
0 tương đương với tất cả các phương thức của
from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
5

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
from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
8. 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, thì 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

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
8 tiêu chuẩn gọi đối tượng có thể gọi được truyền cho 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

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
0 cũng đạt được hiệu quả tương tự

Thí 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

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
8 của đối tượng trong một quy trình riêng biệt

join[[timeout]]

If the optional argument timeout is

[1, 4, 9]
33 [the default], the method blocks until the process whose
[1, 4, 9]
48 method is called terminates. 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. 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. The name is a string used for identification purposes only. It has no semantics. Multiple processes may be given the same name

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[]

Return whether the process is alive

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

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
3 trả về cho đến khi tiến trình con kết thúc

daemon

The process’s daemon flag, a Boolean value. Điều này phải được đặt trước khi

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
3 được gọi

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

When a process exits, it attempts to terminate all of its daemonic child processes

Lưu ý rằng quy trình daemon không được phép tạo quy trình con. Otherwise a daemonic process would leave its children orphaned if it gets terminated when its parent process exits. 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

In addition to the

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
5 API,
from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
0 objects also support the following attributes and methods

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

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
8 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

If the child terminated due to an exception not caught within

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
8, the exit code will be 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

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
0 đượ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

See Authentication keys .

sentinel

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 trình điều khiển 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. On Unix, this is a file descriptor usable with primitives from the
[1, 4, 9]
68 module

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

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
0, 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
from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
0 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

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
3,
[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

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
0

[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

exception multiprocessing. Lỗi xác thực

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

exception multiprocessing. Lỗi hết giờ

Raised by methods with a timeout when the timeout expires

Đườ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

For passing messages one can use

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[]
43 [for a connection between two processes] or a queue [which allows multiple producers and consumers]

Các loạ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[]
41,
[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
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[]
42 trong thư viện tiêu chuẩn. Chúng khác nhau ở 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[]
41 thiếu các phương thức
[1, 4, 9]
95 và
[1, 4, 9]
48 được đưa vào Python 2. 5’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[]
42 class

Nếu bạn sử dụng

[1, 4, 9]
92 thì bạn phải gọi
[1, 4, 9]
99 cho từng 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ệ
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[]
501 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[]
502 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ừ
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[]
504

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

    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[]
    
    505 của hàng đợi trả về
    [1, 4, 9]
    
    40 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[]
    
    507 có thể trả về mà không cần 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[]
    
    501

  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

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[]
509 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[]
510 trong khi nó đang cố gắng sử dụng 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[]
41, 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

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[]
512], 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 là 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

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[]
513 trong số các đố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[]
514 đạ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.
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[]
517 chỉ có thể được sử dụng để nhận tin nhắn 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[]
518 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ệ

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[]
501 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[]
502 thông thường từ 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[]
504 của thư viện tiêu chuẩn được nâng lên để báo hiệu thời gian 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[]
41 thực hiện tất cả các phương pháp 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[]
42 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ể 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[]
526 trên các nền tảng Unix như macOS nơi 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[]
527 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 hầu hết các giây hết thời gian chờ và tăng ngoạ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[]
502 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ệ
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[]
502 [thời gian chờ bị bỏ qua trong trường hợp đó]

Đã thay đổi trong phiên bản 3. 8. Nếu hàng đợi đã đóng,

[1, 4, 9]
74 được nâng lên thay 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[]
538.

put_nowait[obj]

Tương đương vớ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[]
539

nhận[[chặn[, timeout]]]

Xóa và trả lại một mục khỏi 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ó sẵn một mụ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ờ và tăng ngoạ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[]
501 nếu không có mục nào có sẵn trong thời gian đó. Mặt khác [khối là
[1, 4, 9]
40], trả lại một mục nếu có sẵn ngay lập tức, nếu không thì tăng ngoạ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[]
501 [thời gian chờ bị bỏ qua trong trường hợp đó]

Đã thay đổi trong phiên bản 3. 8. Nếu hàng đợi đã đóng,

[1, 4, 9]
74 được nâng lên thay 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[]
546.

get_nowait[]

Tương đương vớ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[]
547

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[]
548 có một số phương thức bổ sung không có 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[]
42. Các phương thức này thường không cần thiết đối với hầu hết mã

đó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. Chủ đề nền sẽ thoát sau khi nó đã xóa tất cả dữ liệu được lưu vào bộ đệm vào đường ống. Điều này được gọi tự động khi hàng đợi được thu gom rác

join_thread[]

Tham gia chủ đề nền. Đ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 ________ 1551 để khiến ________ 1552 không làm gì cả

cancel_join_thread[]

Ngăn chặ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[]
552 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
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[]
552

Tên tốt hơn cho phương pháp này có thể 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[]
555. 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ó một, 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

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 sẽ dẫn đến 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[]
557. 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

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 được đơn giản hóa, rất gần với loạ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[]
559 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

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[]
560,
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[]
561 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[]
505 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
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, 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

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[]
560 đượ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 cuộc gọi
[1, 4, 9]
95 cho mọi mục đã đượ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[]
561 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

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[]
577

Khi không thể xác định số lượng CPU, 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[]
526 được nâng lên

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[]
579

đa xử lý. current_ process[]

Trả về đối tượng

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
0 tương ứng với quy trình hiện tại

Tương tự 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[]
581

đa xử lý. parent_process[]

Trả về đối tượng

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
0 tương ứng với tiến trình cha 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[]
583. Đối với quy trình chí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[]
584 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

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
6 của mô-đun chính. Ví dụ

[1, 4, 9]
7

Nếu 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[]
588 bị bỏ qua thì việc cố chạy tệp thực thi bị đóng băng sẽ 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[]
589

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[]
588 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ì
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[]
588 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à

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,
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[]
27 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[]
28. Trên Windows chỉ có sẵ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[]
27. Trên 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[]
29 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[]
27 luôn được hỗ trợ, vớ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[]
29 là mặc định

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

đa xử lý. get_context[phương thức=Không]

Trả về một đối tượng ngữ cảnh có cùng thuộc tính với 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

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à
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,
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[]
27,
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[]
28.
[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à

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,
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[]
27,
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[]
28 hoặc
[1, 4, 9]
33.
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ặc định trên Unix, 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[]
27 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

đa xử lý. set_executable[có thể thực thi]

Đặt đường dẫn của trình thông dịch Python để sử dụng khi bắt đầu tiến trình con. [Theo mặc đị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[]
612 được sử dụng]. Embedders có thể sẽ cần phải làm một cái gì đó như

[1, 4, 9]
8

trước khi họ có thể tạo các tiến trình con

Đã thay đổi trong phiên bản 3. 4. Hiện được hỗ trợ trên Unix khi sử dụng phương thức khởi độ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[]
27.

Đã thay đổi trong phiên bản 3. 11. Chấp nhận một đối tượng giống đường dẫn .

đa xử lý. set_start_method[phương thức , lực lượng=False]

Đặt phương thức sẽ được sử dụng để bắt đầu các tiến trình con. Đối số phương thức có thể 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[]
29,
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[]
27 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[]
28. 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[]
589 nếu phương thức bắt đầu đã được đặt và lực không phải là
[1, 4, 9]
39. Nếu phương thức là
[1, 4, 9]
33 và lực lượng là
[1, 4, 9]
39 thì phương thức bắt đầu được đặt thành
[1, 4, 9]
33. Nếu phương thức là
[1, 4, 9]
33 và lực lượng là
[1, 4, 9]
40 thì bối cảnh được đặt thành bối cảnh mặc định

Lưu ý rằng điều này nên được gọi nhiều nhất một lần và nó phải được bảo vệ bên trong mệnh đề

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
6 của mô-đun chính

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 không chứa từ tương tự 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[]
626,
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[]
627,
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[]
628,
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[]
629,
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[]
630 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[]
631

Đối tượng kết nối¶

Các đối tượng kết nối cho phép gửi và nhận các đối tượng hoặc chuỗi có thể chọn. Chúng có thể được coi là ổ cắm được kết nối theo định hướng thông báo

Đối tượng kết nối thườ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[]
559 – xem thêm Người nghe và Máy khách .

lớp đa xử lý. sự liên quan. Kết nốigửi[obj]

Gửi một đối tượng đến đầu kia của kết nối sẽ được đọc 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[]
46

Đối tượng phải được picklable. Dưa chua rất lớn [khoảng 32 MiB+, mặc dù nó phụ thuộc vào HĐH] có thể gây ra ngoại lệ

[1, 4, 9]
74

recv[]

Trả lại một đối tượng được gửi từ đầu kia của kết nối 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[]
45. Chặn cho đến khi có thứ gì đó để nhận. 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[]
636 nếu không còn gì để nhận và đầu kia đã đóng

fileno[]

Trả lại bộ mô tả tệp hoặc tay cầm được sử dụng bởi kết nối

đóng[]

Đóng kết nối

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

thăm dò ý kiến[[hết thời gian]]

Trả về xem có bất kỳ dữ liệu nào có sẵn để đọc không

Nếu thời gian chờ không được chỉ định thì nó sẽ quay lại ngay lập tức. Nếu thời gian chờ là một số thì số này chỉ định thời gian tối đa tính bằng giây để chặn. Nếu thời gian chờ là

[1, 4, 9]
33 thì thời gian chờ vô hạn được sử dụng

Lưu ý rằng nhiều đối tượng kết nối có thể được thăm dò cùng một lúc bằng cách sử dụng

[1, 4, 9]
64

send_bytes[bộ đệm[ , offset[, size]]]

Gửi dữ liệu byte từ một đối tượng giống như byte dưới dạng một tin nhắn hoàn chỉnh.

Nếu offset được đưa ra thì dữ liệu được đọc từ vị trí đó trong bộ đệm. Nếu kích thước được đưa ra thì nhiều byte sẽ được đọc từ bộ đệm. Bộ đệm rất lớn [khoảng 32 MiB+, mặc dù nó phụ thuộc vào hệ điều hành] có thể gây ra ngoại lệ

[1, 4, 9]
74

recv_byte[[độ dài tối đa]]

Trả về một thông báo đầy đủ về dữ liệu byte được gửi từ đầu kia của kết nối dưới dạng chuỗi. Chặn cho đến khi có thứ gì đó để nhận. 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[]
636 nếu không còn gì để nhận và đầu kia đã đóng

Nếu độ dài tối đa được chỉ định và thông báo dài hơn độ dài tối đa 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[]
546 sẽ được nâng lên và kết nối sẽ không thể đọc được nữa

Đã thay đổi trong phiên bản 3. 3. Hàm này từng 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[]
642, hiện là bí danh 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[]
546.

recv_bytes_into[bộ đệm[ , offset]]

Đọc vào bộ đệm một thông báo đầy đủ về dữ liệu byte được gửi từ đầu kia của kết nối và trả về số byte trong thông báo. Chặn cho đến khi có thứ gì đó để nhận. 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[]
636 nếu không còn gì để nhận và đầu kia đã đóng

bộ đệm phải là một đối tượng giống như byte có thể ghi . Nếu offset được đưa ra thì thông báo sẽ được ghi vào bộ đệm từ vị trí đó. Độ lệch phải là một số nguyên không âm nhỏ hơn độ dài của bộ đệm [tính bằng byte].

Nếu bộ đệm quá ngắn thì một ngoại lệ

[1, 4, 9]
87 sẽ được đưa ra và thông báo hoàn chỉnh có sẵn dưới dạng
[1, 4, 9]
88 trong đó
[1, 4, 9]
86 là trường hợp ngoại lệ

Đã thay đổi trong phiên bản 3. 3. Bản thân các đối tượng kết nối giờ đây có thể được chuyển giữa các quy 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[]
648 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[]
649.

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

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[]
650 returns the connection object, and
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[]
651 calls
[1, 4, 9]
75.

Ví dụ

[1, 4, 9]
9

Cảnh báo

The

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[]
649 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

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[]
43 you should only use the
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[]
46 and
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[]
45 methods after performing some sort of authentication. Xem Khóa xác thực .

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¶

Nói chung, các nguyên hàm đồng bộ hóa không cần thiết trong chương trình đa xử lý như trong chương trình đa luồng. 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

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[]
658

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

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

A bounded semaphore object. a close analog 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[]
659

A solitary difference from its close analog exists. đối số đầu tiên của 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[]
660 của nó được đặt tên là khối, phù hợp vớ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[]
661

Ghi chú

On macOS, this is indistinguishable from

[1, 4, 9]
17 because
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[]
527 is not implemented on that platform

class multiprocessing. Điều kiện[[khóa]]

A condition variable. an alias 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[]
664

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

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[]
668 method was added.

class multiprocessing. Event

A clone 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[]
669

class multiprocessing. Lock

A non-recursive lock object. a close analog 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[]
670. Khi một quy trình hoặc luồng đã nhận được khóa, các nỗ lực tiếp theo để lấy khóa đó từ bất kỳ quy trình hoặc luồng nào sẽ bị chặn cho đến khi khóa được giải phóng; . Các khái niệm và hành vi 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[]
670 khi nó áp dụng cho luồng được sao chép ở đây 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[]
672 vì nó áp dụng cho cả quy trình hoặc luồng, ngoại trừ như đã lưu ý

Lưu ý rằng

[1, 4, 9]
15 thực sự là một hàm xuất xưởng 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[]
674 được khởi tạo với ngữ cảnh mặc định

[1, 4, 9]
15 hỗ trợ giao thức trình quản lý ngữ cảnh và do đó có thể được sử dụng trong câu lệ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[]
676.

mua lại[chặn=Đúng, timeout=None]

Nhận khóa, chặn hoặc không chặn

Với đối số khối được đặt thành

[1, 4, 9]
39 [mặc định], lệnh gọi phương thức sẽ chặn cho đến khi khóa ở trạng thái mở khóa, sau đó đặt thành bị khóa và trả về
[1, 4, 9]
39. Lưu ý rằng tên của đối số đầu tiên này khác với tên 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[]
679

Với đối số khối được đặt thành

[1, 4, 9]
40, lệnh gọi phương thức không chặn. Nếu khóa hiện đang ở trạng thái khóa, hãy trả lại
[1, 4, 9]
40;

Khi được gọi với giá trị dương, dấu chấm động cho thời gian chờ, hãy chặn tối đa số giây được chỉ định theo thời gian chờ miễn là không thể lấy được khóa. Các yêu cầu có giá trị âm cho thời gian chờ tương đương với thời gian chờ bằng 0. Các yêu cầu có giá trị thời gian chờ là

[1, 4, 9]
33 [mặc định] đặt khoảng thời gian chờ thành vô hạn. Lưu ý rằng cách xử lý giá trị âm hoặc giá trị
[1, 4, 9]
33 cho thời gian chờ khác với hành vi đã triển khai 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[]
679. Đối số thời gian chờ không có ý nghĩa thực tế nếu đối số khối được đặt thành
[1, 4, 9]
40 và do đó bị bỏ qua. Trả về
[1, 4, 9]
39 nếu đã lấy được khóa hoặc
[1, 4, 9]
40 nếu hết thời gian chờ

bản phát hành[]

Phát hành một khóa. Điều này có thể được gọi từ bất kỳ quy trình hoặc luồng nào, không chỉ quy trình hoặc luồng ban đầu có khóa

Hành vi giố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[]
689 ngoại trừ khi được gọi trên khóa không khóa, một
[1, 4, 9]
74 được nâng lên

lớp đa xử lý. RLock

Một đối tượng khóa đệ quy. một tương tự gầ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[]
691. Khóa đệ quy phải được giải phóng bởi quy trình hoặc luồng đã nhận được nó. Khi một quy trình hoặc luồng đã nhận được khóa đệ quy, cùng một quy trình hoặc luồng đó có thể lấy lại nó mà không bị chặn;

Lưu ý rằng

[1, 4, 9]
16 thực sự là một hàm xuất xưởng 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[]
693 được khởi tạo với ngữ cảnh mặc định

[1, 4, 9]
16 hỗ trợ giao thức trình quản lý ngữ cảnh và do đó có thể được sử dụng trong câu lệ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[]
676.

mua lại[chặn=Đúng, timeout=None]

Nhận khóa, chặn hoặc không chặn

Khi được gọi với đối số khối được đặt thành

[1, 4, 9]
39, hãy chặn cho đến khi khóa ở trạng thái không khóa [không thuộc sở hữu của bất kỳ quy trình hoặc luồng nào] trừ khi khóa đã được sở hữu bởi quy trình hoặc luồng hiện tại. Sau đó, quy trình hoặc luồng hiện tại có quyền sở hữu khóa [nếu nó chưa có quyền sở hữu] và mức đệ quy bên trong khóa tăng thêm một, dẫn đến giá trị trả về là
[1, 4, 9]
39. Lưu ý rằng có một số điểm khác biệt trong hành vi của đối số đầu tiên này so với cách triển khai 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[]
698, bắt đầu từ tên của chính đối số đó

Khi được gọi với đối số khối được đặt thành

[1, 4, 9]
40, không chặn. Nếu khóa đã được mua [và do đó được sở hữu] bởi một quy trình hoặc luồng khác, thì quy trình hoặc luồng hiện tại không có quyền sở hữu và mức đệ quy trong khóa không bị thay đổi, dẫn đến giá trị trả về là
[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

Việc sử dụng và hành vi của đối số thời gian chờ giố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[]
661. Lưu ý rằng một số hành vi hết thời gian này khác với các hành vi đã triển khai 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[]
698

bản phát hành[]

Phát hành khóa, giảm mức đệ quy. Nếu sau khi giảm, mức đệ quy bằng 0, hãy đặt lại khóa thành mở khóa [không thuộc sở hữu của bất kỳ quy trình hoặc luồng nào] và nếu bất kỳ quy trình hoặc luồng nào khác bị chặn chờ khóa được mở khóa, hãy cho phép chính xác một trong số chúng tiếp tục. Nếu sau khi giảm, mức đệ quy vẫn khác không, thì khóa vẫn bị khóa và thuộc sở hữu của quy trình gọi hoặc luồng

Chỉ gọi phương thức này khi quá trình gọi hoặc luồng sở hữu khóa. 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[]
538 được nâng lên nếu phương thức này được gọi bởi một quy trình hoặc luồng không phải là chủ sở hữu hoặc nếu khóa ở trạng thái mở khóa [không có chủ sở hữu]. Lưu ý rằng loại ngoại lệ được đưa ra trong tình huống này khác với hành vi được triển khai 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[]
505

lớp đa xử lý. Semaphore[[giá trị]]

Một đối tượng semaphore. một tương tự gầ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[]
506

A solitary difference from its close analog exists. đối số đầu tiên của 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[]
660 của nó được đặt tên là khối, phù hợp vớ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[]
661

Ghi chú

Trên macOS,

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[]
509 không được hỗ trợ, vì vậy, việc 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[]
510 khi hết thời gian chờ sẽ mô phỏng hành vi của chức năng đó bằng cách sử dụng vòng lặp ngủ

Ghi chú

Nếu tín hiệu SIGINT được tạo bởi Ctrl-C đến trong khi luồng chính bị chặn bởi 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[]
511,
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[]
661,
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[]
513,
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[]
514,
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[]
515 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[]
516 thì cuộc gọi sẽ bị gián đoạn ngay lập tức 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[]
517 sẽ được nâng lên

Điều này khác với hành vi 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[]
0 trong đó SIGINT sẽ bị bỏ qua trong khi các cuộc gọi chặn tương đương đang diễn ra

Ghi chú

Một số chức năng của gói 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ó, 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[]
519 sẽ bị vô hiệu hóa và cố gắng nhập nó sẽ dẫn đến lỗ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[]
557. Xem bpo-3770 để biết thêm thông tin

Đố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[]
521 được chia sẻ¶

Có thể tạo các đối tượng dùng chung bằng bộ nhớ dùng chung có thể được kế thừa bởi các tiến trình con

đa xử lý. Giá trị[typecode_or_type , *args, lock=True]

Trả về 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[]
521 được phân bổ từ bộ nhớ dùng chung. Theo mặc định, giá trị trả về thực sự là một trình bao bọc được đồng bộ hóa cho đối tượng. Bản thân đối tượng có thể được truy cập thông qua thuộc tính giá trị của
[1, 4, 9]
00

typecode_or_type xác định loại đối tượng được trả về. nó là loại ctypes hoặc mã loại một ký tự thuộc loại được sử dụng bởi mô-đun

[1, 4, 9]
06. *args được chuyển đến hàm tạo cho loại

Nếu khóa là

[1, 4, 9]
39 [mặc định] thì một đối tượng khóa đệ quy mới được tạo để đồng bộ hóa quyền truy cập vào giá trị. Nếu khóa là đối tượng
[1, 4, 9]
15 hoặc
[1, 4, 9]
16 thì đối tượng đó sẽ được sử dụng để đồng bộ hóa quyền truy cập vào giá trị. Nếu khóa là
[1, 4, 9]
40 thì quyền truy cập vào đối tượng được trả về sẽ không được khóa tự động bảo vệ, vì vậy nó không nhất thiết phải là “quy trình an toàn”

Các hoạt độ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[]
529 liên quan đến đọc và viết không phải là nguyên tử. Vì vậy, nếu, ví dụ, bạn muốn tăng nguyên tử một giá trị được chia sẻ thì không đủ để là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[]
50

Giả sử khóa được liên kết là đệ quy [theo mặc định], thay vào đó, bạn có thể là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[]
51

Lưu ý rằng khóa là đối số chỉ có từ khóa

đa xử lý. Mảng[typecode_or_type , size_or_initializer, *, lock=True]

Return a ctypes array allocated from shared memory. Theo mặc định, giá trị trả về thực sự là một trình bao bọc được đồng bộ hóa cho mảng

typecode_or_type xác định loại phần tử của mảng được trả về. nó là loại ctypes hoặc mã loại một ký tự thuộc loại được sử dụng bởi mô-đun

[1, 4, 9]
06. 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

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

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[]
535 has value and raw attributes which allow one to use it to store and retrieve strings

The
[1, 4, 9]
09 module¶

The

[1, 4, 9]
09 module provides functions for allocating
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[]
521 objects from shared memory which can be inherited by child processes

Ghi chú

Mặc dù có thể lưu trữ một con trỏ trong bộ nhớ dùng chung, hãy nhớ rằng con trỏ này sẽ đề cập đến một vị trí trong không gian địa chỉ của một quy trình cụ thể. 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

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[]
540 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 xác định loại đối tượng được trả về. nó là loại ctypes hoặc mã loại một ký tự thuộc loại được sử dụng bởi mô-đun

[1, 4, 9]
06. *args được chuyển đến hàm tạo cho loại

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

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[]
542 instead to make sure that access is automatically synchronized using a lock

Note that an array 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[]
535 has
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[]
544 and
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[]
545 attributes which allow one to use it to store and retrieve strings – see 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[]
521

multiprocessing. sharedctypes. Array[typecode_or_type , size_or_initializer , * , lock=True]

The same as

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[]
547 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”

Lưu ý rằng khóa là đối số chỉ có từ khóa

multiprocessing. sharedctypes. Value[typecode_or_type , *args , lock=True]

The same as

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[]
552 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”

Lưu ý rằng khóa là đối số chỉ có từ khóa

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
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[]
558 object is created automatically

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

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[]
559 returns the wrapped object and
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[]
560 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

Đã thay đổi trong phiên bản 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. [Trong 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[]
561 là một phân lớp nào đó 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[]
562. ]

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

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

The results printed are

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

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. Một đối tượng người quản lý điều khiển một quy trình máy chủ quản lý các đối tượng được chia sẻ. Other processes can access the shared objects by using proxies

multiprocessing. Người quản lý[]

Returns a started

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[]
563 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

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[]
564 module

class multiprocessing. managers. BaseManager[address=None , authkey=None , serializer='pickle' , ctx=None , * , shutdown_timeout=1. 0]

Create a BaseManager object

Once created one should call

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
3 or
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[]
566 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. Nếu địa chỉ là

[1, 4, 9]
33 thì một địa chỉ tùy ý được chọn

authkey là khóa xác thực sẽ được sử dụng để kiểm tra tính hợp lệ của các kết nối đến quy trình máy chủ. If authkey is

[1, 4, 9]
33 then
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[]
569 is used. Otherwise authkey is used and it must be a byte string

serializer must be

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[]
570 [use
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[]
571 serialization] or
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[]
572 [use
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[]
573 serialization]

ctx is a context object, or

[1, 4, 9]
33 [use the current context]. See the
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 function

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

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[]
576 method. If the shutdown times out, the process is terminated. If terminating the process also times out, the process is killed

Changed in version 3. 11. Added the shutdown_timeout parameter.

start[[initializer[ , initargs]]]

Start a subprocess to start the manager. If initializer is not

[1, 4, 9]
33 then the subprocess will call
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[]
578 when it starts

get_server[]

Returns 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[]
579 object which represents the actual server under the control of the Manager. The
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[]
579 object supports the
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[]
581 method

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

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[]
579 additionally has an
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[]
583 attribute

connect[]

Connect a local manager object to a remote manager process

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

shutdown[]

Stop the process used by the manager. This is only available if

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
3 has been used to start the server process

This can be called multiple times

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

A classmethod which can be used for registering a type or callable with the manager class

typeid is a “type identifier” which is used to identify a particular type of shared object. This must be a string

callable is a callable used for creating objects for this type identifier. If a manager instance will be connected to the server using the

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[]
585 method, or if the create_method argument is
[1, 4, 9]
40 then this can be left as
[1, 4, 9]
33

proxytype is a subclass 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[]
588 which is used to create proxies for shared objects with this typeid. If
[1, 4, 9]
33 then a proxy class is created automatically

exposed is used to specify a sequence of method names which proxies for this typeid should be allowed to access using

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[]
590. [If exposed is
[1, 4, 9]
33 then
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[]
592 is used instead if it exists. ] In the case where no exposed list is specified, all “public methods” of the shared object will be accessible. [Here a “public method” means any attribute which has 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[]
593 method and whose name does not begin with
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[]
594. ]

method_to_typeid is a mapping used to specify the return type of those exposed methods which should return a proxy. It maps method names to typeid strings. [If method_to_typeid is

[1, 4, 9]
33 then
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[]
596 is used instead if it exists. ] If a method’s name is not a key of this mapping or if the mapping is
[1, 4, 9]
33 then the object returned by the method will be copied by value

create_method determines whether a method should be created with name typeid which can be used to tell the server process to create a new shared object and return a proxy for it. By default it is

[1, 4, 9]
39

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[]
599 instances also have one read-only property

address

The address used by the manager

Changed in version 3. 3. Manager objects support the context management protocol – see Context Manager Types .

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[]
650 starts the server process [if it has not already started] and then returns the manager object.
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[]
651 calls
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[]
576.

In previous versions

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[]
650 did not start the manager’s server process if it was not already started

class multiprocessing. managers. SyncManager

A subclass 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[]
599 which can be used for the synchronization of processes. Objects of this type are returned by
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

Its methods create and return Proxy Objects for a number of commonly used data types to be synchronized across processes. This notably includes shared lists and dictionaries.

Barrier[parties[ , action[ , timeout]]]

Create a shared

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[]
658 object and return a proxy for it

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

BoundedSemaphore[[value]]

Create a shared

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[]
659 object and return a proxy for it

Condition[[lock]]

Create a shared

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[]
664 object and return a proxy for it

If lock is supplied then it should be a proxy for 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[]
670 or
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[]
691 object

Changed in version 3. 3. The

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[]
668 method was added.

Event[]

Create a shared

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[]
669 object and return a proxy for it

Lock[]

Create a shared

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[]
670 object and return a proxy for it

Namespace[]

Create a shared

[1, 4, 9]
14 object and return a proxy for it

Queue[[maxsize]]

Create a shared

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[]
42 object and return a proxy for it

RLock[]

Create a shared

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[]
691 object and return a proxy for it

Semaphore[[value]]

Create a shared

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[]
506 object and return a proxy for it

Array[typecode , sequence]

Create an array and return a proxy for it

Giá trị[mã loại , giá trị]

Create an object with a writable

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[]
544 attribute and return a proxy for it

dict[]dict[mapping]dict[sequence]

Create a shared

[1, 4, 9]
13 object and return a proxy for it

list[]list[sequence]

Create a shared

[1, 4, 9]
12 object and return a proxy for it

Changed in version 3. 6. Shared objects are capable of being nested. For example, a shared container object such as a shared list can contain other shared objects which will all be managed and synchronized by the

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[]
563.

class multiprocessing. managers. Namespace

A type that can register with

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[]
563

A namespace object has no public methods, but does have writable attributes. Its representation shows the values of its attributes

However, when using a proxy for a namespace object, an attribute beginning with

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[]
594 will be an attribute of the proxy and not an attribute of the referent

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[]
56

Customized managers¶

To create one’s own manager, one creates a subclass 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[]
599 and uses 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[]
25 classmethod to register new types or callables with the manager class. For example

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

Using a remote manager¶

It is possible to run a manager server on one machine and have clients use it from other machines [assuming that the firewalls involved allow it]

Running the following commands creates a server for a single shared queue which remote clients can access

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[]
58

One client can access the server as follows

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[]
59

Another client can also use it

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[]
60

Local processes can also access that queue, using the code from above on the client to access it remotely

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[]
61

Proxy Objects¶

A proxy is an object which refers to a shared object which lives [presumably] in a different process. The shared object is said to be the referent of the proxy. Multiple proxy objects may have the same referent

A proxy object has methods which invoke corresponding methods of its referent [although not every method of the referent will necessarily be available through the proxy]. In this way, a proxy can be used just like its referent can

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[]
62

Notice that applying

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 to a proxy will return the representation of the referent, whereas applying
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 will return the representation of the proxy

An important feature of proxy objects is that they are picklable so they can be passed between processes. As such, a referent can contain Proxy Objects . This permits nesting of these managed lists, dicts, and other Proxy Objects .

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

Similarly, dict and list proxies may be nested inside one another

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[]
64

If standard [non-proxy]

[1, 4, 9]
12 or
[1, 4, 9]
13 objects are contained in a referent, modifications to those mutable values will not be propagated through the manager because the proxy has no way of knowing when the values contained within are modified. However, storing a value in a container proxy [which triggers 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[]
30 on the proxy object] does propagate through the manager and so to effectively modify such an item, one could re-assign the modified value to the container proxy

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[]
65

This approach is perhaps less convenient than employing nested Proxy Objects for most use cases but also demonstrates a level of control over the synchronization.

Ghi chú

The proxy types 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[]
6 do nothing to support comparisons by value. So, for instance, we have

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[]
66

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

class multiprocessing. managers. BaseProxy

Proxy objects are instances of subclasses 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[]
588

_callmethod[methodname[ , args[ , kwds]]]

Call and return the result of a method of the proxy’s referent

If

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 is a proxy whose referent is
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 then the expression

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[]
67

will evaluate the expression

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[]
68

in the manager’s process

The returned value will be a copy of the result of the call or a proxy to a new shared object – see documentation for the method_to_typeid argument of

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

If an exception is raised by the call, then is re-raised by

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. If some other exception is raised in the manager’s process then this is converted into 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[]
37 exception and is raised by
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

Note in particular that an exception will be raised if methodname has not been exposed

An example of the usage of

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

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[]
69

_getvalue[]

Return a copy of the referent

If the referent is unpicklable then this will raise an exception

__repr__[]

Return a representation of the proxy object

__str__[]

Return the representation of the referent

Cleanup¶

A proxy object uses a weakref callback so that when it gets garbage collected it deregisters itself from the manager which owns its referent

A shared object gets deleted from the manager process when there are no longer any proxies referring to it

Process Pools¶

One can create a pool of processes which will carry out tasks submitted to it with the

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 class

class multiprocessing. pool. Pool[[processes[ , initializer[ , initargs[ , maxtasksperchild[ , context]]]]]]

A process pool object which controls a pool of worker processes to which jobs can be submitted. It supports asynchronous results with timeouts and callbacks and has a parallel map implementation

processes is the number of worker processes to use. If processes is

[1, 4, 9]
33 then the number returned by
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[]
579 is used

If initializer is not

[1, 4, 9]
33 then each worker process will call
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[]
578 when it starts

maxtasksperchild is the number of tasks a worker process can complete before it will exit and be replaced with a fresh worker process, to enable unused resources to be freed. The default maxtasksperchild is

[1, 4, 9]
33, which means worker processes will live as long as the pool

context can be used to specify the context used for starting the worker processes. Usually a pool is created using the function

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 or 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[]
47 method of a context object. In both cases context is set appropriately

Note that the methods of the pool object should only be called by the process which created the pool

Cảnh bá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[]
48 objects have internal resources that need to be properly managed [like any other resource] by using the pool as a context manager or by calling
[1, 4, 9]
75 and
[1, 4, 9]
71 manually. Failure to do this can lead to the process hanging on finalization

Note that it is not correct to rely on the garbage collector to destroy the pool as CPython does not assure that the finalizer of the pool will be called [see

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 for more information]

New in version 3. 2. maxtasksperchild

New in version 3. 4. context

Ghi chú

Worker processes within 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 typically live for the complete duration of the Pool’s work queue. A frequent pattern found in other systems [such as Apache, mod_wsgi, etc] to free resources held by workers is to allow a worker within a pool to complete only a set amount of work before being exiting, being cleaned up and a new process spawned to replace the old one. The maxtasksperchild argument to the
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 exposes this ability to the end user

apply[func[ , args[ , kwds]]]

Call func with arguments args and keyword arguments kwds. It blocks until the result is ready. Given this blocks,

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 is better suited for performing work in parallel. 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]]]]]

A variant of 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[]
55 method which returns 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[]
56 object

If callback is specified then it should be a callable which accepts a single argument. When the result becomes ready callback is applied to it, that is unless the call failed, in which case the error_callback is applied instead

If error_callback is specified then it should be a callable which accepts a single argument. If the target function fails, then the error_callback is called with the exception instance

Callbacks should complete immediately since otherwise the thread which handles the results will get blocked

map[func , iterable[ , chunksize]]

A parallel equivalent of 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[]
57 built-in function [it supports only one iterable argument though, for multiple iterables see
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]. It blocks until the result is ready

This method chops the iterable into a number of chunks which it submits to the process pool as separate tasks. The [approximate] size of these chunks can be specified by setting chunksize to a positive integer

Note that it may cause high memory usage for very long iterables. Consider 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[]
59 or
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 with explicit chunksize option for better efficiency

map_async[func , iterable[ , chunksize[ , callback[ , error_callback]]]]

A variant of 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[]
57 method which returns 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[]
56 object

If callback is specified then it should be a callable which accepts a single argument. When the result becomes ready callback is applied to it, that is unless the call failed, in which case the error_callback is applied instead

If error_callback is specified then it should be a callable which accepts a single argument. If the target function fails, then the error_callback is called with the exception instance

Callbacks should complete immediately since otherwise the thread which handles the results will get blocked

imap[func , iterable[ , chunksize]]

A lazier version of

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

The chunksize argument is the same as the one used by 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[]
57 method. For very long iterables using a large value for chunksize can make the job complete much faster than using the default value of
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

Also if chunksize is

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 then 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[]
67 method of the iterator returned by 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[]
59 method has an optional timeout parameter.
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 will raise
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 if the result cannot be returned within timeout seconds

imap_unordered[func , iterable[ , chunksize]]

The same as

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 except that the ordering of the results from the returned iterator should be considered arbitrary. [Only when there is only one worker process is the order guaranteed to be “correct”. ]

starmap[func , iterable[ , chunksize]]

Like

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 except that the elements of the iterable are expected to be iterables that are unpacked as arguments

Hence an iterable of

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 results 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[]
74

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

starmap_async[func , iterable[ , chunksize[ , callback[ , error_callback]]]]

A combination of

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 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[]
76 that iterates over iterable of iterables and calls func with the iterables unpacked. Returns a result object

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

đóng[]

Prevents any more tasks from being submitted to the pool. Once all the tasks have been completed the worker processes will exit

chấm dứt[]

Stops the worker processes immediately without completing outstanding work. When the pool object is garbage collected

[1, 4, 9]
71 will be called immediately

tham gia[]

Wait for the worker processes to exit. One must call

[1, 4, 9]
75 or
[1, 4, 9]
71 before using
[1, 4, 9]
48

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

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[]
650 returns the pool object, and
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[]
651 calls
[1, 4, 9]
71.

class multiprocessing. pool. AsyncResult

The class of the result returned by

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 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[]
85

get[[timeout]]

Return the result when it arrives. If timeout is not

[1, 4, 9]
33 and the result does not arrive within timeout seconds then
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 is raised. If the remote call raised an exception then that exception will be reraised by
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[]
560

wait[[timeout]]

Wait until the result is available or until timeout seconds pass

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ì
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[]
538.

Ví dụ sau minh họa việc sử dụng pool

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

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

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[]
514 được trả về bở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[]
43

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ề

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[]
514

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 họ là
[1, 4, 9]
33 thì họ được suy ra từ 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

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[]
514. 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 đượ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

address

Đị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 có thì nó 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 .

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[]
650 trả về đối tượng người nghe 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[]
651 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

    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[]
    
    514 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 đượ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
    from multiprocessing import Process, Pipe
    
    def f[conn]:
        conn.send[[42, None, 'hello']]
        conn.close[]
    
    if __name__ == '__main__':
        parent_conn, child_conn = Pipe[]
        p = Process[target=f, args=[child_conn,]]
        p.start[]
        print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
        p.join[]
    
    0

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. The difference is that, if
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 is interrupted by a signal, it can raise
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[]
546 with an error number 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[]
25, whereas
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 will not

Windows. An item in object_list must either be an integer handle which is waitable [according to the definition used by the documentation of the Win32 function

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[]
27] or it can be an object with 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[]
28 method which returns a socket handle or pipe handle. [Note that pipe handles and socket handles are not waitable handles. ]

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

ví dụ

The following server code creates a listener which uses

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 as an authentication key. It then waits for a connection and sends some data to the client

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

The following code connects to the server and receives some data from the server

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

The following code uses

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 to wait for messages from multiple processes at once

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

Address Formats¶

  • Đị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 đượ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

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[]
569 sẽ được sử dụng [xem
from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
0]. Giá trị này sẽ được tự động kế thừa bởi bất kỳ đối tượng
from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
0 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, bộ ghi có cấp độ 150 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, hàm này 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ý

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

Để 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 biệt, 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ý ngữ 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
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[]
579 được sử dụng

If initializer is not

[1, 4, 9]
33 then each worker process will call
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[]
578 when it starts

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 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 thức 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, nói chung nên 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" đưa 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

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

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ụ

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[]
56

nên được viết lại 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[]
57

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

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[]
58

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 trong quy trình. Điều này đã được thay đổi thà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[]
59

Đ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 ẩn 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
from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
0 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ằng trình thông dịch Python mới mà không gây ra các 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

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[]
589

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

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[]
588 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

from multiprocessing import Process, Pipe

def f[conn]:
    conn.send[[42, None, 'hello']]
    conn.close[]

if __name__ == '__main__':
    parent_conn, child_conn = Pipe[]
    p = Process[target=f, args=[child_conn,]]
    p.start[]
    print[parent_conn.recv[]]   # prints "[42, None, 'hello']"
    p.join[]
01 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ả

Bạn có thể song song hóa các vòng lặp trong Python không?

Bạn có thể chuyển đổi các vòng lặp for lồng nhau để thực thi đồng thời hoặc song song trong Python bằng cách sử dụng nhóm luồng hoặc nhóm quy trình , tùy thuộc vào loại tác vụ đang được thực thi.

Cách sử dụng đa xử lý trong Python cho

Điều này có thể đạt được bằng cách tạo một thể hiện Quy trình và chỉ định hàm sẽ thực thi bằng cách sử dụng đối số “đích” trong hàm tạo của lớp . Sau đó, chúng ta có thể gọi phương thức start[] để bắt đầu tiến trình con mới và bắt đầu thực thi hàm đích trong tiến trình con.

Đa xử lý có phải là Python song song không?

Đa xử lý Python. Xử lý song song dựa trên quy trình trong Python . Vì lý do này, Tính năng đa xử lý của Python thực hiện tính song song dựa trên quy trình .

Làm cách nào để chuyển nhiều đối số trong Python đa xử lý?

Bản đồ nhóm đa xử lý[] Nhiều đối số .
sử dụng hồ bơi. apply_async[] Thay vào đó
sử dụng hồ bơi. starmap[] Thay vào đó
Thay đổi chức năng mục tiêu thành giải nén đối số
Sử dụng hàm Wrapper để giải nén đối số

Chủ Đề