2017-04-16 17 views
10

Tôi có một nhiệm vụ đơn giản như thế:.Python multiprocessing.Queue vs multiprocessing.manager() Queue()

def worker(queue): 
    while True: 
     try: 
      _ = queue.get_nowait() 
     except Queue.Empty: 
      break 

if __name__ == '__main__': 
    manager = multiprocessing.Manager() 
    # queue = multiprocessing.Queue() 
    queue = manager.Queue() 

    for i in range(5): 
     queue.put(i) 

    processes = [] 

    for i in range(2): 
     proc = multiprocessing.Process(target=worker, args=(queue,)) 
     processes.append(proc) 
     proc.start() 

    for proc in processes: 
     proc.join() 

Dường như multiprocessing.Queue thể làm tất cả công việc mà tôi cần, nhưng mặt khác Tôi thấy nhiều ví dụ về người quản lý() Queue() và không thể hiểu được những gì tôi thực sự cần. Trông giống như Manager() Queue() sử dụng một số loại đối tượng proxy, nhưng tôi không hiểu mục đích đó, bởi vì multiprocessing.Queue() làm cùng một công việc mà không có bất kỳ đối tượng proxy nào.

Vì vậy, câu hỏi của tôi là:

1) Điều gì thực sự khác biệt giữa multiprocessing.Queue và đối tượng được trả về bởi multiprocessing.manager() Queue().?

2) Tôi cần sử dụng gì?

+3

Điều này có thể hữu ích. https://code.activestate.com/lists/python-tutor/99586/ –

Trả lời

8

Mặc dù hiểu biết của tôi còn hạn chế về chủ đề này, từ những gì tôi đã làm tôi có thể nói đó là một trong những khác biệt chính giữa multiprocessing.Queue() và multiprocessing.Manager() Queue():.

  • đa xử lý. Queue() là một đối tượng trong khi multiprocessing.Manager() Queue() là một địa chỉ (proxy) trỏ đến hàng đợi chia sẻ được quản lý bởi đối tượng multiprocessing.Manager().
  • do đó bạn không thể chuyển các đối tượng đa xử lý thông thường.Queue() cho các phương thức Pool, bởi vì nó không thể được chọn.
  • Hơn nữa python doc cho chúng ta đặc biệt chú ý khi sử dụng multiprocessing.Queue() vì nó có thể có những ảnh hưởng không mong muốn

Note Khi một đối tượng được đặt trên một hàng đợi, các đối tượng được ngâm và một chủ đề nền sau sẽ xóa dữ liệu đã được nạp vào một đường ống bên dưới. Điều này có một số hậu quả gây ngạc nhiên một chút, nhưng 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ì bạn có thể sử dụng hàng đợi được tạo với người quản lý. Sau khi đặt một đối tượng vào một hàng trống, có thể có độ trễ cực nhỏ trước khi phương thức empty() của hàng đợi trả về False và get_nowait() có thể trả về mà không cần nâng lên Queue.Empty. Nếu nhiều quá trình là các đối tượng enqueuing, nó có thể cho các đối tượng được nhận ở đầu kia out-of-order. Tuy nhiên, các đối tượng được enqueued bởi cùng một quá trình sẽ luôn luôn được theo thứ tự mong đợi đối với nhau.

Cảnh báo Như đã đề cập ở trên, nếu quá trình con đã đặt các mục vào hàng đợi (và nó không được sử dụng JoinableQueue.cancel_join_thread), thì quá trình đó sẽ không chấm dứt cho đến khi tất cả các mục đệm đã được xả vào đường ống. Điều này có nghĩa rằng nếu bạn cố gắng tham gia quá trình đó, bạn có thể bị 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 tiêu thụ. Tương tự như vậy, nếu tiến trình con không phải là daemonic thì quá trình cha mẹ có thể treo trên lối ra khi nó cố gắng tham gia tất cả các con không daemonemon của nó. Lưu ý rằng hàng đợi được tạo bằng trình quản lý không có vấn đề này.

Có một workaround để sử dụng multiprocessing.Queue() có bể bơi bằng cách thiết lập hàng đợi như là một biến toàn cầu và thiết lập nó cho tất cả các quá trình lúc khởi tạo:

queue = multiprocessing.Queue() 
def initialize_shared(q): 
    global queue 
    queue=q 

pool= Pool(nb_process,initializer=initialize_shared, initargs(queue,)) 

sẽ tạo ra các quy trình hồ bơi với chia sẻ một cách chính xác hàng đợi nhưng chúng ta có thể tranh luận rằng các đối tượng multiprocessing.Queue() không được tạo ra cho việc sử dụng này.

Mặt khác, trình quản lý.Queue() có thể được chia sẻ giữa các quy trình phụ nhóm bằng cách chuyển nó làm đối số bình thường của hàm.

Theo ý kiến ​​của tôi, sử dụng multiprocessing.Manager(). Hàng đợi() là tốt trong mọi trường hợp và ít phiền toái hơn. Có thể có một số hạn chế bằng cách sử dụng một người quản lý nhưng tôi không nhận thức được nó.