The
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]6 module also introduces APIs which do not have analogs 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[]0 module. A prime example of this is 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 object which offers a convenient means of parallelizing the execution of a function across multiple input values, distributing the input data across processes [data parallelism]. The following example demonstrates the common practice of defining such functions in a module so that child processes can successfully import that module. This basic example of data parallelism 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[]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]]]
will print to standard output
[1, 4, 9]
See also
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 offers a higher level interface to push tasks to a background process without blocking execution of the calling process. Compared to 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[]5 interface directly, 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[]9 API more readily allows the submission of work to the underlying process pool to be separated from waiting for the results
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[]
0 class¶
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, processes are spawned by creating 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 object and then calling its
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 method.
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 follows the API of
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. A trivial example of a multiprocess program is
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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
To show the individual process IDs involved, here is an expanded 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[]6
For an explanation of why 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[]6 part is necessary, see Programming guidelines .
Contexts and start methods¶
Depending on the platform,
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 supports three ways to start a process. These start methods are
spawn
The parent process starts a fresh Python interpreter process. The child process will only inherit those resources necessary to run the process object’s
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 method. In particular, unnecessary file descriptors and handles from the parent process will not be inherited. Starting a process using this method is rather slow compared to using fork or forkserverAvailable on Unix and Windows. The default on Windows and macOS
forkThe parent process uses
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 to fork the Python interpreter. The child process, when it begins, is effectively identical to the parent process. All resources of the parent are inherited by the child process. Note that safely forking a multithreaded process is problematicAvailable on Unix only. The default on Unix
forkserverWhen the program starts and selects the forkserver start method, a server process is started. From then on, whenever a new process is needed, the parent process connects to the server and requests that it fork a new process. 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ừaCó sẵn trên các nền tảng Unix hỗ trợ chuyển bộ mô tả tệp qua các đường ống Unix
Đã thay đổi trong phiên bản 3. 8. Trên macOS, phương thức bắt đầu sinh sản hiện là mặc định. Phương pháp bắt đầu ngã ba nên được coi là không an toàn vì nó có thể dẫn đến sự cố của quy trình con. Xem bpo-33725.
Đã thay đổi trong phiên bản 3. 4. đã thêm spawn trên tất cả các nền tảng Unix và thêm máy chủ phân nhánh cho một số nền tảng Unix. Các tiến trình con không còn kế thừa tất cả các xử lý có thể kế thừa của cha mẹ trên Windows.
Trên Unix, 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. 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[]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. Cụ thể, các khóa được tạo bằng bối cảnh ngã ba không thể được chuyển đến các quy trình được bắt đầu bằng phương pháp bắt đầu sinh sản hoặc máy chủ ngã ba
Một thư viện muốn sử dụng một phương thức bắt đầu cụ thể có lẽ nên sử dụng
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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
Các phương thức bắt đầ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[]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 hiện không thể được sử dụng với các tệp thực thi "đóng băng" [i. e. , các tệp nhị phân được tạo bởi các gói như PyInstaller và cx_Freeze] trên Unix. Phương thức bắt đầu của
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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ớpfrom multiprocessing import Process, Queue def f[q]: q.put[[42, 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ứcfrom multiprocessing import Process, Queue def f[q]: q.put[[42, 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. Tất nhiên, không có nguy cơ tham nhũng từ các quy trình sử dụng các đầu khác nhau của đường ống cùng một lúc
Đồng bộ hóa giữa các quy trình¶
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]6 chứa các giá trị tương đương của tất cả các nguyên mẫu đồng bộ hóa từ
from multiprocessing import Process, Queue def f[q]: q.put[[42, None, 'hello']] if __name__ == '__main__': q = Queue[] p = Process[target=f, args=[q,]] p.start[] print[q.get[]] # prints "[42, None, 'hello']" p.join[]0. Chẳng hạn, người ta có thể sử dụng khóa để đảm bảo rằng mỗi lần chỉ có một quy trình in ra đầu ra tiêu chuẩn
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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. Điều này đặc biệt đúng khi sử dụng nhiều quy trình
Tuy nhiên, nếu bạn thực sự cần sử dụng một số dữ liệu được chia sẻ thì
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]6 sẽ cung cấp một số cách để thực hiện việc đó
Bộ nhớ dùng chung
Dữ liệu có thể được lưu trữ trong bản đồ bộ nhớ dùng chung bằng cách sử dụng
[1, 4, 9]00 hoặc[1, 4, 9]01. Ví dụ, đoạn mã saufrom multiprocessing import Process, Queue def f[q]: q.put[[42, None, 'hello']] if __name__ == '__main__': q = Queue[] p = Process[target=f, args=[q,]] p.start[] print[q.get[]] # prints "[42, None, 'hello']" p.join[]4sẽ in
[1, 4, 9]0Cá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 proxyNgười quản lý do
[1, 4, 9]10 trả lại sẽ hỗ trợ các loại[1, 4, 9]12,[1, 4, 9]13,[1, 4, 9]14,[1, 4, 9]15,[1, 4, 9]16,[1, 4, 9]17,[1, 4, 9]18,[1, 4, 9]19,[1, 4, 9]20,[1, 4, 9]21,from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 và[1, 4, 9]01. Ví dụ,[1, 4, 9]1sẽ in
[1, 4, 9]2Trình quản lý quy trình máy chủ linh hoạt hơn so với việc sử dụng các đối tượng bộ nhớ dùng chung vì chúng có thể được tạo để hỗ trợ các loại đối tượng tùy ý. Ngoài ra, một trình quản lý duy nhất có thể được chia sẻ bởi các quy trình trên các máy tính khác nhau qua mạng. Tuy nhiên, chúng chậm hơn so với sử dụng bộ nhớ dùng chung
Sử dụng một nhóm công nhân¶
Lớp
from multiprocessing import Process, Queue def f[q]: q.put[[42, None, 'hello']] if __name__ == '__main__': q = Queue[] p = Process[target=f, args=[q,]] p.start[] print[q.get[]] # prints "[42, None, 'hello']" p.join[]5 đại diện cho một nhóm các worker process. Nó có các phương thức cho phép các tác vụ được giảm tải cho các quy trình công nhân theo một số cách khác nhau
Ví dụ
[1, 4, 9]3
Lưu ý rằng các phương thức của một nhóm chỉ nên được sử dụng bởi quy trình đã tạo ra nó
Ghi chú
Chức năng trong gói này yêu cầu trẻ em có thể nhập mô-đun
[1, 4, 9]26. Điều này được đề cập trong Hướng dẫn lập trình tuy nhiên nó đáng để chỉ ra ở đây. Điều này có nghĩa là một số ví dụ, chẳng hạn như ví dụ
[1, 4, 9]27 sẽ không hoạt động trong trình thông dịch tương tác. Ví dụ.
[1, 4, 9]4
[Nếu bạn thử điều này, nó sẽ thực sự tạo ra ba lần theo dõi đầy đủ được xen kẽ theo kiểu bán ngẫu nhiên, và sau đó bạn có thể phải dừng quá trình gốc bằng cách nào đó. ]
Tài liệu tham khảo¶
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, 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]5bắ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ệttham gia[[hết thời gian]]¶
Nếu thời gian chờ của đối số tùy chọn là
[1, 4, 9]33 [mặc định], phương thức sẽ chặn cho đến khi quá trình có phương thức
[1, 4, 9]48 được gọi kết thúc. Nếu thời gian chờ là một số dương, nó sẽ chặn tối đa các giây hết thời gian chờ. Lưu ý rằng phương thức trả về
[1, 4, 9]33 nếu quá trình của nó kết thúc hoặc nếu phương thức hết thời gian. Kiểm tra
[1, 4, 9]50 của quy trình để xác định xem nó có bị chấm dứt hay không
Một quá trình có thể được tham gia nhiều lần
Một quá trình không thể tự tham gia vì điều này sẽ gây ra bế tắc. Có lỗi khi cố gắng tham gia một quy trình trước khi nó được bắt đầu
tên ¶Tên quy trình. Tên là một chuỗi chỉ được sử dụng cho mục đích nhận dạng. Nó không có ngữ nghĩa. Nhiều quá trình có thể được đặt tên giống nhau
Tên ban đầu được đặt bởi hàm tạo. Nếu không có tên rõ ràng nào được cung cấp cho hàm tạo, tên có dạng 'Process-N1. N2. …. Nk' được xây dựng, trong đó mỗi Nk là con thứ N của cha mẹ của nó
is_alive[] ¶Trả về xem quá trình có còn hoạt động không
Đại khái, một đối tượng tiến trình 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úcdaemon ¶
Cờ daemon của tiến trình, một giá trị Boolean. Đ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
Khi một tiến trình thoát, nó sẽ cố gắng chấm dứt tất cả các tiến trình con daemon của nó
Lưu ý rằng quy trình daemon không được phép tạo quy trình con. Mặt khác, một quy trình daemon sẽ khiến các con của nó mồ côi nếu nó bị chấm dứt khi quá trình cha mẹ của nó thoát ra. Ngoài ra, đây không phải là dịch vụ hoặc daemon Unix, chúng là các quy trình bình thường sẽ bị chấm dứt [và không được tham gia] nếu các quy trình không phải daemon đã thoát
Ngoài API
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, các đố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ũng hỗ trợ các thuộc tính và phương thức saupid ¶
Trả lại ID tiến trình. Trước khi quá trình được sinh ra, đây sẽ là
[1, 4, 9]33mã 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
Nếu đứa trẻ bị chấm dứt do một ngoại lệ không bị bắt trong
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, mã thoát sẽ là 1. Nếu nó bị kết thúc bởi tín hiệu N, mã thoát sẽ là giá trị âm -Nkhó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
Xem Khóa xác thực .
trọng điểm ¶Một điều khiển số của một đối tượng hệ thống sẽ trở thành "sẵn sàng" khi quá trình kết thúc
Bạn có thể sử dụng giá trị này nếu muốn đợi nhiều sự kiện cùng lúc bằng cách sử dụng
[1, 4, 9]64. Mặt khác, gọi
[1, 4, 9]48 đơn giản hơn
Trên Windows, đây là một 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. Trên Unix, đây là một bộ mô tả tệp có thể sử dụng được với các nguyên mẫu từ mô-đun
[1, 4, 9]68
Mới trong phiên bản 3. 3
chấm dứt[] ¶Chấm dứt quá trình. Trên Unix, điều này được thực hiện bằng tín hiệu
[1, 4, 9]69; . Lưu ý rằng các trình xử lý thoát và các mệnh đề cuối cùng, v.v. , sẽ không được thực hiện
Lưu ý rằng các tiến trình con của tiến trình sẽ không bị chấm dứt – chúng sẽ đơn giản trở nên mồ côi
Cảnh báo
Nếu phương pháp này được sử dụng khi quy trình được liên kết đang sử dụng đường ống hoặc hàng đợi thì đường ống hoặc hàng đợi đó có thể bị hỏng và có thể trở nên không sử dụng được bởi quy trình khác. Tương tự, nếu quá trình đã có khóa hoặc semaphore, v.v. sau đó chấm dứt nó có khả năng gây ra bế tắc cho các quá trình khác
giết[] ¶Tương tự như
[1, 4, 9]71 nhưng sử dụng tín hiệu
[1, 4, 9]72 trên Unix
Mới trong phiên bản 3. 7
đóng[] ¶Đóng đối tượng
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]6ngoạ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[]6ngoạ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 bytengoại lệ đa xử lý. Lỗi xác thực ¶
Xảy ra khi có lỗi xác thực
ngoại lệ đa xử lý. Lỗi hết giờ ¶Tăng theo các phương thức có thời gian chờ khi hết thời gian chờ
Đường ống và hàng đợi¶
Khi sử dụng nhiều quy trình, người ta thường sử dụng tính năng truyền thông báo để liên lạc giữa các quy trình và tránh phải sử dụng bất kỳ nguyên tắc đồng bộ hóa nào như khóa
Để truyền tin nhắn, người ta có thể sử dụng
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 [để kết nối giữa hai quy trình] hoặc hàng đợi [cho phép nhiều nhà sản xuất và người tiêu dùng]
Các loại
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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. lớp 5 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
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ý.
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ăngfrom multiprocessing import Process, Queue def f[q]: q.put[[42, None, 'hello']] if __name__ == '__main__': q = Queue[] p = Process[target=f, args=[q,]] p.start[] print[q.get[]] # prints "[42, None, 'hello']" p.join[]
501Nế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ắnlớ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]48qsize[] ¶
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 khaitrố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
Put obj into the queue. If the optional argument block is
[1, 4, 9]39 [the default] and timeout is
[1, 4, 9]33 [the default], block if necessary until a free slot is available. If timeout is a positive number, it blocks at most timeout seconds and raises 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[]502 exception if no free slot was available within that time. Otherwise [block is
[1, 4, 9]40], put an item on the queue if a free slot is immediately available, else raise 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[]502 exception [timeout is ignored in that case]
Changed in version 3. 8. If the queue is closed,
[1, 4, 9]74 is raised instead of
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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] ¶
Equivalent to
from multiprocessing import Process, Queue def f[q]: q.put[[42, None, 'hello']] if __name__ == '__main__': q = Queue[] p = Process[target=f, args=[q,]] p.start[] print[q.get[]] # prints "[42, None, 'hello']" p.join[]539nhậ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. If timeout is a positive number, it blocks at most timeout seconds and raises 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[]501 exception if no item was available within that time. Otherwise [block is
[1, 4, 9]40], return an item if one is immediately available, else raise the
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 exception [timeout is ignored in that case]
Changed in version 3. 8. If the queue is closed,
[1, 4, 9]74 is raised instead of
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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[] ¶
Equivalent to
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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ờ chuyển dữ liệu đã xử lý sang đườ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ướilớ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]40lấ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]48task_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 đợitham 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
See also
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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ối ¶ gử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]74recv[] ¶
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 đã đóngfileno[] ¶
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]64send_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]74recv_bytes[[maxlength]] ¶
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. Blocks until there is something to receive. Raises
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 if there is nothing left to receive and the other end has closed
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
buffer must be a writable bytes-like object . 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 trả về đối tượng kết nối 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.
Ví dụ
[1, 4, 9]9
Cảnh báo
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[]649 tự động giải nén dữ liệu mà nó nhận được, đây có thể là một rủi ro bảo mật trừ khi bạn có thể tin tưởng vào quy trình gửi tin nhắn
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
Nếu một quá trình bị giết trong khi nó đang cố đọc hoặc ghi vào một đường dẫn thì dữ liệu trong đường dẫn đó có khả năng bị hỏng, vì có thể không thể chắc chắn ranh giới của thông báo nằm ở đâu
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
Lưu ý rằng người ta cũng có thể tạo nguyên mẫu đồng bộ hóa bằng cách sử dụng đối tượng người quản lý – xem Người quản lý .
lớp đa xử lý. Barrier[parties[ , action[ , timeout]]] ¶Đối tượng rào cản. 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
lớp đa xử lý. BoundedSemaphore[[giá trị]]¶Một đối tượng semaphore giới hạn. 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[]659
Một sự khác biệt duy nhất từ tương tự gần của nó tồn tại. đố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, điều này không thể phân biệt được với
[1, 4, 9]17 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[]527 không được triển khai trên nền tảng đóclass multiprocessing. Điều kiện[[khóa]]¶
Biến điều kiện. một bí danh cho
from multiprocessing import Process, Queue def f[q]: q.put[[42, None, 'hello']] if __name__ == '__main__': q = Queue[] p = Process[target=f, args=[q,]] p.start[] print[q.get[]] # prints "[42, None, 'hello']" p.join[]664
Nếu lock được chỉ định thì nó phải là một đối tượng
[1, 4, 9]15 hoặc
[1, 4, 9]16 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
Đã thay đổi trong phiên bản 3. 3. 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[]668 đã được thêm vào. lớp đa xử lý. Sự kiện ¶
Một bản sao 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[]669lớp đa xử lý. Khóa ¶
Một đối tượng khóa không đệ quy. 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. Once a process or thread has acquired a lock, subsequent attempts to acquire it from any process or thread will block until it is released; any process or thread may release it. 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 ý
Note that
[1, 4, 9]15 is actually a factory function which returns an instance 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[]674 initialized with a default context
[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]¶
Acquire a lock, blocking or non-blocking
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
With the block argument set to
[1, 4, 9]40, the method call does not block. Nếu khóa hiện đang ở trạng thái khóa, hãy trả lại
[1, 4, 9]40;
When invoked with a positive, floating-point value for timeout, block for at most the number of seconds specified by timeout as long as the lock can not be acquired. 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. The timeout argument has no practical implications if the block argument is set to
[1, 4, 9]40 and is thus ignored. 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ênlớp đa xử lý. RLock ¶
Một đối tượng khóa đệ quy. 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[]691. A recursive lock must be released by the process or thread that acquired it. 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]¶
Acquire a lock, blocking or non-blocking
When invoked with the block argument set to
[1, 4, 9]39, block until the lock is in an unlocked state [not owned by any process or thread] unless the lock is already owned by the current process or thread. 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. Note that there are several differences in this first argument’s behavior compared to the implementation 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[]698, starting with the name of the argument itself
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. Note that some of these behaviors of timeout differ from the implemented behaviors in
from multiprocessing import Process, Queue def f[q]: q.put[[42, None, 'hello']] if __name__ == '__main__': q = Queue[] p = Process[target=f, args=[q,]] p.start[] print[q.get[]] # prints "[42, None, 'hello']" p.join[]698bản phát hành[] ¶
Phát hành khóa, giảm mức đệ quy. If after the decrement the recursion level is zero, reset the lock to unlocked [not owned by any process or thread] and if any other processes or threads are blocked waiting for the lock to become unlocked, allow exactly one of them to proceed. 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
Only call this method when the calling process or thread owns the lock. 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[]538 is raised if this method is called by a process or thread other than the owner or if the lock is in an unlocked [unowned] state. 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[]505lớ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
Một sự khác biệt duy nhất từ tương tự gần của nó tồn tại. đố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,
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 is unsupported, so calling
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 with a timeout will emulate that function’s behavior using a sleeping loop
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ý. Value[typecode_or_type , *args , lock=True] ¶Return 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[]521 object 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 đố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ị. 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. 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
multiprocessing. Mảng[typecode_or_type , size_or_initializer, *, lock=True]¶Trả về một mảng ctypes đượ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 mảng
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. Nếu size_or_initializer là một số nguyên, thì nó xác định độ dài của mảng và ban đầu mảng sẽ bằng 0. Otherwise, size_or_initializer is a sequence which is used to initialize the array and whose length determines the length of the array
Nếu khóa là
[1, 4, 9]39 [mặc định] thì một đối tượng khóa 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”
Lưu ý rằng khóa chỉ là một đối số từ khóa
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
Mô-đun [1, 4, 9]
09¶
Mô-đun
[1, 4, 9]09 cung cấp các hàm để cấp phát 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[]521 từ bộ nhớ dùng chung có thể được kế thừa bởi các tiến trình con
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ể. Tuy nhiên, con trỏ rất có thể không hợp lệ trong ngữ cảnh của quy trình thứ hai và việc cố gắng hủy đăng ký con trỏ khỏi quy trình thứ hai có thể gây ra sự cố
multiprocessing. sharedctypes. RawArray[typecode_or_type , size_or_initializer] ¶Trả về một mảng ctypes được phân bổ từ bộ nhớ dùng chung
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. Nếu size_or_initializer là một số nguyên thì nó xác định độ dài của mảng và ban đầu mảng sẽ bằng 0. 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đa xử lý. 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
Lưu ý rằng cài đặt và nhận giá trị có khả năng không phải là nguyên tử – thay vào đó hãy 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[]542 để đảm bảo rằng quyền truy cập được tự động đồng bộ hóa bằng cách sử dụng khóa
Lưu ý rằng một mảng 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[]535 có 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[]544 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[]545 cho phép một người sử dụng nó để lưu trữ và truy xuất các chuỗi – xem tài liệu 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[]521đa xử lý. sharedctypes. Mảng[typecode_or_type , size_or_initializer, *, lock=True]¶
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[]547 ngoại trừ tùy thuộc vào giá trị của khóa, trình bao bọc đồng bộ hóa an toàn cho quy trình có thể được trả về thay vì một mảng ctypes thô
Nếu khóa là
[1, 4, 9]39 [mặc định] thì một đối tượng khóa 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”
Lưu ý rằng khóa là đối số chỉ có từ khóa
đa xử lý. sharedctypes. Giá trị[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
Nếu khóa là
[1, 4, 9]39 [mặc định] thì một đối tượng khóa 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”
Lưu ý rằng khóa là đối số chỉ có từ khóa
đa xử lý. sharedctypes. bản sao[obj] ¶Return a ctypes object allocated from shared memory which is a copy of the ctypes object obj
đa xử lý. sharedctypes. synchronized[obj[ , lock]] ¶Trả về một đối tượng trình bao an toàn cho một đối tượng ctypes sử dụng khóa để đồng bộ hóa quyền truy cập. Nếu khóa là
[1, 4, 9]33 [mặc định] thì đố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[]558 được tạo tự động
Một trình bao bọc được đồng bộ hóa sẽ có hai phương thức ngoài các phương thức của đối tượng mà nó bao bọ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[]559 trả về đối tượng được bọ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[]560 trả về đối tượng khóa được sử dụng để đồng bộ hóa
Lưu ý rằng việc truy cập đối tượng ctypes thông qua trình bao bọc có thể chậm hơn rất nhiều so với truy cập đối tượng ctypes thô
Đã thay đổi trong phiên bản 3. 5. Synchronized objects support the context manager protocol.
Bảng bên dưới so sánh cú pháp tạo các đối tượng ctypes dùng chung từ bộ nhớ dùng chung với cú pháp ctypes bình thường. [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 sử dụng loại
sharedctypes sử dụng mã kiểu
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
Kết quả in ra 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[]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ẻ. Các quy trình khác có thể truy cập các đối tượng được chia sẻ bằng cách sử dụng proxy
đa xử lý. Manager[] ¶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[]563 đã bắt đầu có thể được sử dụng để chia sẻ các đối tượng giữa các quy trình. 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. Các lớp người quản lý được định nghĩa 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[]564lớp đa xử lý. quản lý. Trình quản lý cơ sở[địa chỉ=Không có . 0, authkey=None, serializer='pickle', ctx=None, *, shutdown_timeout=1.0] ¶
Tạo đối tượng BaseManager
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. If address is
[1, 4, 9]33 then an arbitrary one is chosen
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ủ. Nếu authkey là
[1, 4, 9]33 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[]569 được sử dụng. Nếu không thì authkey được sử dụng và nó phải là một chuỗi byte
bộ nối tiếp 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[]570 [sử dụng tuần tự hó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[]571] 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[]572 [sử dụng tuần tự hó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[]573]
ctx là một đối tượng ngữ cảnh hoặc
[1, 4, 9]33 [sử dụng ngữ cảnh hiện tại]. Xem 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[]25
shutdown_timeout là thời gian chờ tính bằng giây được sử dụng để đợi cho đến khi quá trình được người quản lý sử dụng hoàn thành trong 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[]576. Nếu hết thời gian tắt máy, quá trình kết thúc. Nếu kết thúc quá trình cũng hết thời gian, quá trình bị hủy
Đã thay đổi trong phiên bản 3. 11. Added the shutdown_timeout parameter.
start[[initializer[ , initargs]]] ¶Bắt đầu một quy trình con để khởi động trình quản lý. Nếu trình khởi tạo không phải là
[1, 4, 9]33 thì quy trình con sẽ 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[]578 khi nó bắt đầuget_server[] ¶
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[]579 đại diện cho máy chủ thực dưới sự kiểm soát của Trình quản lý. Đối tượng
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 hỗ trợ 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[]581
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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
Ngoài ra,
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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òn 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[]583kết nối[] ¶
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[]55tắt máy[] ¶
Stop the process used by the manager. Điều này chỉ khả dụng nếu
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 sử dụng để bắt đầu quá trình máy chủ
Điều này có thể được gọi nhiều lần
register[typeid[ , callable[ , proxytype[ , exposed[ , method_to_typeid[ , create_method]]]]]] ¶Một phương thức lớp có thể được sử dụng để đăng ký một loại hoặc có thể gọi được với lớp người quản lý
typeid is a “type identifier” which is used to identify a particular type of shared object. Đây phải là một chuỗi
có thể gọi được là một có thể gọi được sử dụng để tạo các đối tượng cho loại định danh này. Nếu một phiên bản trình quản lý sẽ được kết nối với máy chủ bằng 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[]585 hoặc nếu đối số phương thức tạo_tạo là
[1, 4, 9]40 thì điều này có thể được để lại là
[1, 4, 9]33
proxytype là một lớp con của
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 được sử dụng để tạo proxy cho các đối tượng dùng chung với typeid này. Nếu
[1, 4, 9]33 thì một lớp proxy được tạo tự động
được sử dụng để chỉ định một chuỗi tên phương thức mà proxy cho typeid này sẽ được phép truy cập bằng cách sử dụng
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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. ] Trong trường hợp không có danh sách hiển thị nào được chỉ định, tất cả các “phương thức công khai” của đối tượng được chia sẻ sẽ có thể truy cập được. [Ở đây “phương thức công khai” có nghĩa là bất kỳ thuộc tính nào có phương thức
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 và tên của nó không bắt đầu 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[]594. ]
method_to_typeid is a mapping used to specify the return type of those exposed methods which should return a proxy. Nó ánh xạ các tên phương thức thành các chuỗi typeid. [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. ] Nếu tên của phương thức không phải là khóa của ánh xạ này hoặc nếu ánh xạ là
[1, 4, 9]33 thì đối tượng được phương thức trả về sẽ được sao chép theo giá trị
create_method xác định xem một phương thức có nên được tạo với tên typeid có thể được sử dụng để báo cho quy trình máy chủ tạo một đối tượng dùng chung mới và trả về proxy cho nó hay không. Theo mặc định, nó là
[1, 4, 9]39
Phiên bản
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 cũng có một thuộc tính chỉ đọcđịa chỉ ¶
The address used by the manager
Đã thay đổi trong phiên bản 3. 3. Các đối tượng trình quản lý hỗ trợ giao thức quản lý ngữ cảnh – xem Các loại trình quản lý ngữ cảnh .
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 cuộ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[]576.
Trong các phiên bản trướ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[]650 không bắt đầu quy trình máy chủ của người quản lý nếu nó chưa được bắt đầulớp đa xử lý. quản lý. Trình quản lý đồng bộ hóa ¶
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
Các phương thức của nó tạo và trả về Đối tượng proxy cho một số loại dữ liệu thường được sử dụng để đồng bộ hóa giữa các quy trình. This notably includes shared lists and dictionaries.
Rào cản[các bên[ , action[, timeout]]]¶Tạo 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[]658 được chia sẻ và trả về một proxy cho nó
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Điều kiện[[khóa]]¶
Tạo 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[]664 được chia sẻ và trả về một proxy cho nó
Nếu lock được cung cấp thì nó phải là proxy cho đối tượng
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 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[]691
Đã thay đổi trong phiên bản 3. 3. 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[]668 đã được thêm vào. Event[] ¶
Tạo 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[]669 được chia sẻ và trả về một proxy cho nóKhóa[] ¶
Tạo 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[]670 được chia sẻ và trả về một proxy cho nóKhông gian tên[] ¶
Tạo đối tượng
[1, 4, 9]14 được chia sẻ và trả lại proxy cho đối tượng đóHàng đợi[[kích thước tối đa]]¶
Tạo 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[]42 được chia sẻ và trả về một proxy cho nóRLock[] ¶
Tạo 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[]691 được chia sẻ và trả về một proxy cho nóSemaphore[[giá trị]]¶
Tạo 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[]506 được chia sẻ và trả về một proxy cho nóArray[typecode , sequence] ¶
Tạo một mảng và trả về một proxy cho nó
Giá trị[mã loại , giá trị]¶Tạo một đối tượng có thuộc tính
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 có thể ghi và trả về một proxy cho đối tượng đódict[] ¶ dict[mapping]dict[sequence]
Create a shared
[1, 4, 9]13 object and return a proxy for itdanh sách[] ¶ danh sách[sequence]
Tạo đối tượng
[1, 4, 9]12 được chia sẻ và trả lại proxy cho đối tượng đó
Đã thay đổi trong phiên bản 3. 6. Các đối tượng được chia sẻ có khả năng được lồng vào nhau. 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. lớp đa xử lý. quản lý. Không gian tên ¶
Một loại có thể đăng ký 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[]563
Một đối tượng không gian tên không có phương thức công khai, nhưng có các thuộc tính có thể ghi. Đại diện của nó cho thấy các giá trị của các thuộc tính của nó
Tuy nhiên, khi sử dụng proxy cho đối tượng không gian tên, thuộc tính bắt đầu bằng
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 sẽ là thuộc tính của proxy chứ không phải thuộc tính của tham 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[]56
Trình quản lý tùy chỉnh¶
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. 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[]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]
Chạy các lệnh sau sẽ tạo một máy chủ cho một hàng đợi được chia sẻ duy nhất mà các máy khách từ xa có thể truy cập
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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
Một khách hàng có thể truy cập máy chủ 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[]59
Một khách hàng khác cũng có thể sử dụng 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[]60
Các quy trình cục bộ cũng có thể truy cập hàng đợi đó, sử dụng mã từ phía trên trên máy khách để truy cập từ xa
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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
Đối tượng ủy quyền¶
Proxy là một đối tượng đề cập đến một đối tượng được chia sẻ tồn tại [có lẽ] trong một quy trình khác. Đối tượng được chia sẻ được cho là tham chiếu của proxy. Multiple proxy objects may have the same referent
Một đối tượng proxy có các phương thức gọi các phương thức tương ứng của tham chiếu của nó [mặc dù không phải mọi phương thức của tham chiếu đều nhất thiết phải có sẵn thông qua proxy]. Bằng cách này, một proxy có thể được sử dụng giống như người tham chiếu của nó có thể
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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
Lưu ý rằng việc áp dụng
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]26 cho proxy sẽ trả về biểu diễn của tham chiếu, trong khi áp dụng
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]27 sẽ trả về biểu diễn của proxy
Một tính năng quan trọng của các đối tượng proxy là chúng có thể chọn được để chúng có thể được chuyển giữa các quy trình. Như vậy, một tham chiếu có thể chứa Đối tượng proxy . Điều này cho phép lồng các danh sách được quản lý này, lệnh và các Đối tượng proxy khác.
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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
Tương tự, proxy dict và list có thể được lồng vào nhau
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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
Nếu các đối tượng tiêu chuẩn [không phải proxy]
[1, 4, 9]12 hoặc
[1, 4, 9]13 được chứa trong một tham chiếu, các sửa đổi đối với các giá trị có thể thay đổi đó sẽ không được truyền qua trình quản lý vì proxy không có cách nào biết khi nào các giá trị chứa trong đó được sửa đổi. Tuy nhiên, việc lưu trữ một giá trị trong proxy vùng chứa [kích hoạt
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]30 trên đối tượng proxy] sẽ lan truyền qua trình quản lý và do đó, để sửa đổi mục đó một cách hiệu quả, người ta có thể gán lại giá trị đã sửa đổi cho proxy vùng chứa
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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ú
Các loại proxy trong
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]6 không làm gì để hỗ trợ so sánh theo giá trị. 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
One should just use a copy of the referent instead when making comparisons
lớp đa xử lý. managers. Proxy cơ sở ¶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[tên phương thức[ , args[, kwds]]]¶
Gọi và trả về kết quả của một phương thức tham chiếu của proxy
Nếu
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]33 là proxy có tham chiếu là
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]34 thì biểu thức
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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
Nếu một ngoại lệ được đưa ra bởi cuộc gọi, thì sẽ được đưa ra lại bởi
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]36. Nếu một số ngoại lệ khác được đưa ra trong quy trình của người quản lý thì điều này được chuyển đổi thành ngoại lệ
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]37 và được đưa ra bởi
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]36
Note in particular that an exception will be raised if methodname has not been exposed
Một ví dụ về việc sử dụng
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]36
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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[] ¶
Trả lại một bản sao của người giới thiệu
Nếu người giới thiệu không thể chọn được thì điều này sẽ đưa ra một ngoại lệ
__repr__[] ¶Return a representation of the proxy object
__str__[] ¶Trả về đại diện của tham chiếu
Dọn dẹp¶
Một đối tượng proxy sử dụng một cuộc gọi lại yếu để khi nó được thu gom rác, nó sẽ tự hủy đăng ký khỏi trình quản lý sở hữu tham chiếu của nó
Một đối tượng được chia sẻ sẽ bị xóa khỏi quy trình quản lý khi không còn bất kỳ proxy nào đề cập đến nó
Nhóm quy trình¶
Người ta có thể tạo một nhóm các quy trình sẽ thực hiện các tác vụ được gửi cho nó với lớp
from multiprocessing import Process, Queue def f[q]: q.put[[42, None, 'hello']] if __name__ == '__main__': q = Queue[] p = Process[target=f, args=[q,]] p.start[] print[q.get[]] # prints "[42, None, 'hello']" p.join[]5lớp đa xử lý. hồ bơi. Nhóm[[quy trình[, initializer[, initargs[, maxtasksperchild[, context]]]]]]¶
Một đối tượng nhóm quy trình kiểm soát nhóm quy trình công nhân mà công việc có thể được gửi tới. Nó hỗ trợ các kết quả không đồng bộ với thời gian chờ và gọi lại và có triển khai bản đồ song song
quy trình là số lượng quy trình công nhân để sử dụng. Nếu các quy trình là
[1, 4, 9]33 thì số được trả về bởi
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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
Nếu trình khởi tạo không phải là
[1, 4, 9]33 thì mỗi worker process sẽ gọi
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 khi nó bắt đầu
maxtasksperchild là số lượng tác vụ mà một worker process có thể hoàn thành trước khi nó thoát và được thay thế bằng một worker process mới, để cho phép giải phóng các tài nguyên không sử dụng. Maxtaskperchild mặc định là
[1, 4, 9]33, có nghĩa là worker process sẽ tồn tại miễn là pool
bối cảnh có thể được sử dụng để chỉ định bối cảnh được sử dụng để bắt đầu các quy trình worker. Thông thường, một nhóm được tạo bằng cách sử dụng hàm
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]46 hoặc phương thức
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]47 của một đối tượng bối cảnh. Trong cả hai trường hợp bối cảnh được thiết lập một cách thích hợp
Lưu ý rằng các phương thức của đối tượng nhóm chỉ nên được gọi bởi quá trình tạo nhóm
Cảnh báo
Các đối tượng
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]48 có tài nguyên nội bộ cần được quản lý đúng cách [giống như bất kỳ tài nguyên nào khác] bằng cách sử dụng nhóm làm trình quản lý bối cảnh hoặc bằng cách gọi thủ công
[1, 4, 9]75 và
[1, 4, 9]71. Không làm điều này có thể dẫn đến quá trình bị treo khi quyết toán
Lưu ý rằng việc dựa vào trình thu gom rác để phá hủy nhóm là không đúng vì CPython không đảm bảo rằng trình hoàn thiện của nhóm sẽ được gọi [xem
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]51 để biết thêm thông tin]
New in version 3. 2. maxtaskperchild
New in version 3. 4. bối cảnh
Ghi chú
Các quy trình công nhân trong một
from multiprocessing import Process, Queue def f[q]: q.put[[42, None, 'hello']] if __name__ == '__main__': q = Queue[] p = Process[target=f, args=[q,]] p.start[] print[q.get[]] # prints "[42, None, 'hello']" p.join[]5 thường tồn tại trong toàn bộ thời lượng của hàng đợi công việc của Nhóm. Một mô hình phổ biến được tìm thấy trong các hệ thống khác [chẳng hạn như Apache, mod_wsgi, v.v.] để giải phóng tài nguyên do công nhân nắm giữ là cho phép một công nhân trong nhóm chỉ hoàn thành một lượng công việc nhất định trước khi thoát, được dọn sạch và một quy trình mới được sinh ra . Đối số maxtasksperchild cho
from multiprocessing import Process, Queue def f[q]: q.put[[42, None, 'hello']] if __name__ == '__main__': q = Queue[] p = Process[target=f, args=[q,]] p.start[] print[q.get[]] # prints "[42, None, 'hello']" p.join[]5 hiển thị khả năng này cho người dùng cuốiapply[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. Additionally, func is only executed in one of the workers of the poolapply_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. Khi kết quả sẵn sàng gọi lại được áp dụng cho nó, đó là trừ khi cuộc gọi không thành công, trong trường hợp đó, error_callback được áp dụng thay thế
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 efficiencymap_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. Khi kết quả sẵn sàng gọi lại được áp dụng cho nó, đó là trừ khi cuộc gọi không thành công, trong trường hợp đó, error_callback được áp dụng thay thế
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 secondsimap_unordered[func , iterable[ , chunksize]] ¶
Giống như
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]59 ngoại trừ thứ tự của kết quả từ trình vòng lặp được trả về nên được coi là tùy ý. [Only when there is only one worker process is the order guaranteed to be “correct”. ]starmap[func , có thể lặp lại[, 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 immediatelytham 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[]85get[[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[]560wait[[timeout]] ¶
Wait until the result is available or until timeout seconds pass
ready[] ¶Return whether the call has completed
successful[] ¶Return whether the call completed without raising an exception. Will raise
[1, 4, 9]74 if the result is not ready
Changed in version 3. 7. If the result is not ready,
[1, 4, 9]74 is raised instead 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[]538.
The following example demonstrates the use of a 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
Listeners and Clients¶
Usually message passing between processes is done using queues or by 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[]514 objects 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[]43
However, 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[]94 module allows some extra flexibility. It basically gives a high level message oriented API for dealing with sockets or Windows named pipes. It also has support for digest authentication using 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[]95 module, and for polling multiple connections at the same timemultiprocessing. connection. deliver_challenge[connection , authkey] ¶
Send a randomly generated message to the other end of the connection and wait for a reply
If the reply matches the digest of the message using authkey as the key then a welcome message is sent to the other end of the connection. Otherwise
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 is raisedmultiprocessing. connection. answer_challenge[connection , authkey] ¶
Receive a message, calculate the digest of the message using authkey as the key, and then send the digest back
If a welcome message is not received, 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[]96 is raisedmultiprocessing. connection. Client[address[ , family[ , authkey]]] ¶
Attempt to set up a connection to the listener which is using address address, returning 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[]514
The type of the connection is determined by family argument, but this can generally be omitted since it can usually be inferred from the format of address. [See Address Formats ]
If authkey is given and not None, it should be a byte string and will be used as the secret key for an HMAC-based authentication challenge. No authentication is done if authkey is None.
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 is raised if authentication fails. See Authentication keys . class multiprocessing. connection. Listener[[address[ , family[ , backlog[ , authkey]]]]] ¶
A wrapper for a bound socket or Windows named pipe which is ‘listening’ for connections
address is the address to be used by the bound socket or named pipe of the listener object
Ghi chú
If an address of ‘0. 0. 0. 0’ is used, the address will not be a connectable end point on Windows. If you require a connectable end-point, you should use ‘127. 0. 0. 1’
family is the type of socket [or named pipe] to use. This can be one of the strings
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 [for a TCP socket],
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 [for a Unix domain socket] 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[]02 [for a Windows named pipe]. Of these only the first is guaranteed to be available. If family is
[1, 4, 9]33 then the family is inferred from the format of address. If address is also
[1, 4, 9]33 then a default is chosen. This default is the family which is assumed to be the fastest available. See Address Formats . Note that if family is
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 and address is
[1, 4, 9]33 then the socket will be created in a private temporary directory created 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[]07.
If the listener object uses a socket then backlog [1 by default] is passed 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[]08 method of the socket once it has been bound
If authkey is given and not None, it should be a byte string and will be used as the secret key for an HMAC-based authentication challenge. No authentication is done if authkey is None.
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 is raised if authentication fails. See Authentication keys . accept[] ¶
Accept a connection on the bound socket or named pipe of the listener object and return 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[]514 object. If authentication is attempted and fails, 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[]96 is raisedđóng[] ¶
Close the bound socket or named pipe of the listener object. This is called automatically when the listener is garbage collected. However it is advisable to call it explicitly
Listener objects have the following read-only properties
địa chỉ ¶The address which is being used by the Listener object
last_accepted ¶Địa chỉ mà từ đó kết nối được chấp nhận cuối cùng đến. If this is unavailable then it is
[1, 4, 9]33
New in version 3. 3. Listener 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 listener 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. multiprocessing. connection. wait[object_list , timeout=None] ¶
Wait till an object in object_list is ready. Returns the list of those objects in object_list which are ready. If timeout is a float then the call blocks for at most that many seconds. If timeout is
[1, 4, 9]33 then it will block for an unlimited period. A negative timeout is equivalent to a zero timeout
For both Unix and Windows, an object can appear in object_list if it is
a readable
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 object;a connected and readable
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 object; orthe
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 attribute of afrom 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 object
A connection or socket object is ready when there is data available to be read from it, or the other end has been closed
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 almost equivalent
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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. [Lưu ý rằng tay cầm ống và tay cầm ổ cắm không phải là tay cầm có thể chờ được. ]
Mới trong phiên bản 3. 3
Examples
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¶
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[]
00 address is a tuple of the formfrom multiprocessing import Process, Queue def f[q]: q.put[[42, 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 where hostname is a string and port is an integerAn
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 address is a string representing a filename on the filesystemAn
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 address is a string of the formfrom multiprocessing import Process, Queue def f[q]: q.put[[42, 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. To usefrom multiprocessing import Process, Queue def f[q]: q.put[[42, 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 to connect to a named pipe on a remote computer called ServerName one should use an address of the formfrom multiprocessing import Process, Queue def f[q]: q.put[[42, 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 instead
Note that any string beginning with two backslashes is assumed by default to be 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[]02 address rather than 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[]01 address
Authentication keys¶
When one 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[]40, the data received is automatically unpickled. Unfortunately unpickling data from an untrusted source is a security risk. Therefore
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 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[]36 use the
import multiprocessing as mp def foo[q]: q.put['hello'] if __name__ == '__main__': ctx = mp.get_context['spawn'] q = ctx.Queue[] p = ctx.Process[target=foo, args=[q,]] p.start[] print[q.get[]] p.join[]95 module to provide digest authentication
An authentication key is a byte string which can be thought of as a password. once a connection is established both ends will demand proof that the other knows the authentication key. [Demonstrating that both ends are using the same key does not involve sending the key over the connection. ]
If authentication is requested but no authentication key is specified then the return value 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[]569 is used [see
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]. This value will be automatically inherited by any
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 object that the current process creates. Đ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
Suitable authentication keys can also be generated by using
[1, 4, 9]61
Logging¶
Một số hỗ trợ cho ghi nhật ký có sẵn. Note, however, that 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[]48 package does not use process shared locks so it is possible [depending on the handler type] for messages from different processes to get mixed upmultiprocessing. get_logger[] ¶
Returns the logger used 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[]6. If necessary, a new one will be created
Khi được tạo lần đầu, bộ ghi có cấp độ 150 và không có trình xử lý mặc định. Messages sent to this logger will not by default propagate to the root logger
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
Below is an example session with logging turned on
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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
For a full table of logging levels, 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[]48 module
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[]
57 module¶
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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
In particular, 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 function provided 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[]57 returns an instance 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[]63, which 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[]5 that supports all the same method calls but uses a pool of worker threads rather than worker processesclass multiprocessing. hồ bơi. ThreadPool[[processes[ , 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
processes is the number of worker threads 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
Nếu trình khởi tạo không phải là
[1, 4, 9]33 thì mỗi worker process sẽ gọi
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 khi nó bắt đầu
Unlike
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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, maxtasksperchild and context cannot be provided
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ô-đunfrom multiprocessing import Process, Queue def f[q]: q.put[[42, 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. As such, it inherits some operations that don’t make sense for a pool backed by threads, and it has its own type for representing the status of asynchronous jobs,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, that is not understood by any other librariesUsers should generally prefer to 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[]78, which has a simpler interface that was designed around threads from the start, and which returnsfrom multiprocessing import Process, Queue def f[q]: q.put[[42, 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 instances that are compatible with many other libraries, includingfrom multiprocessing import Process, Queue def f[q]: q.put[[42, 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¶
There are certain guidelines and idioms which should be adhered to when 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[]6
Tất cả các phương thức bắt đầu¶
The following applies to all start methods
Avoid shared state
As far as possible one should try to avoid shifting large amounts of data between processes
It is probably best to stick to using queues or pipes for communication between processes rather than using the lower level synchronization primitives
Picklability
Ensure that the arguments to the methods of proxies are picklable
Thread safety of proxies
Do not use a proxy object from more than one thread unless you protect it with a lock
[There is never a problem with different processes using the same proxy. ]
Joining zombie processes
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. There should never be very many because each time a new process starts [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[]82 is called] all completed processes which have not yet been joined will be joined. Also calling a finished process’sfrom multiprocessing import Process, Queue def f[q]: q.put[[42, 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 will join the process. Even so it is probably good practice to explicitly join all the processes that you start
Better to inherit than pickle/unpickle
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. However, one should generally avoid sending shared objects to other processes using pipes or queues. Instead you should arrange the program so that a process which needs access to a shared resource created elsewhere can inherit it from an ancestor process
Avoid terminating processes
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[]85 method to stop a process is liable to cause any shared resources [such as locks, semaphores, pipes and queues] currently being used by the process to become broken or unavailable to other processesTherefore it is probably best to only consider 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[]85 on processes which never use any shared resources
Joining processes that use queues
Bear in mind that a process that has put items in a queue will wait before terminating until all the buffered items are fed by the “feeder” thread to the underlying pipe. [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. ]This means that whenever you use a queue you need to make sure that all items which have been put on the queue will eventually be removed before the process is joined. Otherwise you cannot be sure that processes which have put items on the queue will terminate. Cũng nên nhớ rằng các quy trình không phải daemon sẽ được tự động tham gia
An example which will deadlock is the following
from multiprocessing import Process, Queue def f[q]: q.put[[42, None, 'hello']] if __name__ == '__main__': q = Queue[] p = Process[target=f, args=[q,]] p.start[] print[q.get[]] # prints "[42, None, 'hello']" p.join[]55Cá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]
Explicitly pass resources to child processes
On Unix using the fork start method, a child process can make use of a shared resource created in a parent process using a global resource. 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
Apart from making the code [potentially] compatible with Windows and the other start methods this also ensures that as long as the child process is still alive the object will not be garbage collected in the parent process. Đ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
So for instance
from multiprocessing import Process, Queue def f[q]: q.put[[42, None, 'hello']] if __name__ == '__main__': q = Queue[] p = Process[target=f, args=[q,]] p.start[] print[q.get[]] # prints "[42, None, 'hello']" p.join[]56should be rewritten 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[]57
Beware of replacing
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 with a “file like object”
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 originally unconditionally calledfrom multiprocessing import Process, Queue def f[q]: q.put[[42, None, 'hello']] if __name__ == '__main__': q = Queue[] p = Process[target=f, args=[q,]] p.start[] print[q.get[]] # prints "[42, None, 'hello']" p.join[]58in 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[]91 method — this resulted in issues with processes-in-processes. This has been changed tofrom multiprocessing import Process, Queue def f[q]: q.put[[42, None, 'hello']] if __name__ == '__main__': q = Queue[] p = Process[target=f, args=[q,]] p.start[] print[q.get[]] # prints "[42, None, 'hello']" p.join[]59Which solves the fundamental issue of processes colliding with each other resulting in a bad file descriptor error, but introduces a potential danger to applications which replace
from multiprocessing import Process, Queue def f[q]: q.put[[42, 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 with a “file-like object” with output buffering. This danger is that if multiple processes call[1, 4, 9]75 on this file-like object, it could result in the same data being flushed to the object multiple times, resulting in corruptionIf you write a file-like object and implement your own caching, you can make it fork-safe by storing the pid whenever you append to the cache, and discarding the cache when the pid changes. For example
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[]0For more information, see bpo-5155, bpo-5313 and bpo-5331
The spawn and forkserver start methods¶
There are a few extra restriction which don’t apply to the fork start method
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ớpfrom 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ứcfrom multiprocessing import Process, Queue def f[q]: q.put[[42, 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ọiTuy 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
Make sure that the main module can be safely imported by a new Python interpreter without causing unintended side effects [such a starting a new process]
For example, using the spawn or forkserver start method running the following module would fail 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[]589import 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[]1Thay 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ư sauimport 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[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[]588 line can be omitted if the program will be run normally instead of frozen. ]This allows the newly spawned Python interpreter to safely import the module and then run the module’s
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 functionSimilar restrictions apply if a pool or manager is created in the main module
Examples¶
Demonstration of how to create and use customized managers and proxies
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ả