2017-04-16 7 views
10

는 :.파이썬 multiprocessing.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() 

이 multiprocessing.Queue 내가 필요한 모든 일을하지만, 다른 한편으로 할 수있는 것 손 관리자()의 많은 예를 봅니다. 대기열()과 내가 정말로 필요한 것을 이해할 수 없습니다. Manager()처럼 보입니다. Queue()는 일종의 프록시 객체를 사용하지만, 다중 처리 .Queue()가 프록시 객체없이 동일한 작업을 수행하기 때문에 이러한 목적을 이해하지 못합니다.

그래서, 내 질문은 다음과 같습니다

() 대기열 multiprocessing.manager에 의해 반환

1) 정말로 차이 multiprocessing.Queue와 객체 사이의().?

2) 무엇을 사용해야합니까? 나의 이해는 내가 multiprocessing.Queue()와 multiprocessing.Manager() 사이에 하나 개의 주요 차이가 말할 수있는 한 일에서이 주제에 대한 제한되어 있지만

+3

도움이 될 수 있습니다. https://code.activestate.com/lists/python-tutor/99586/ –

답변

8

큐().

  • 멀티. Queue()는 객체이고 multiprocessing.Manager() 인 반면 Queue()는 multiprocessing.Manager() 객체가 관리하는 공유 대기열을 가리키는 주소 (프록시)입니다.
  • 따라서 일반 멀티 프로세싱 .Queue() 객체는 절편 처리 할 수 ​​없으므로 Pool 메서드에 전달할 수 없습니다.
  • 더욱이 python doc이 multiprocessing.Queue()를 사용할 때 의도하지 않은 효과

객체가 큐에 넣어 주을 가질 수 있기 때문에 특별한주의를 지불하는 우리에게, 개체가 절인된다 백그라운드 스레드는 나중에 피클 링 된 데이터를 기본 파이프로 플러시합니다. 이것은 다소 놀라운 일이지만, 실제적인 어려움을 일으키지 않아야합니다. 관리자가 만든 대기열을 대신 사용할 수 있습니다. 빈 대기열에 객체를 놓은 후 대기열의 empty() 메소드가 False를 반환하고 get_nowait()이 Queue.Empty를 발생시키지 않고 리턴 할 수 있기 전에 무한 지연이있을 수 있습니다. 여러 프로세스가 객체를 대기열에 추가하는 경우 객체가 순서가 맞지 않는 다른 쪽에서 수신 될 수 있습니다. 그러나 동일한 프로세스에 의해 대기열에 포함 된 오브젝트는 항상 서로에 대해 예상 된 순서대로 존재합니다. 버퍼링 된 모든 항목이 파이프로 플러시 될 때까지 자식 프로세스가 큐에 항목을 걸었다 (그리고 JoinableQueue.cancel_join_thread 사용하지 않은) 경우, 전술 한 바와 같이

경고는, 그 처리는 종료하지 않을 것이다. 즉, 해당 프로세스에 참여하려고하면 대기열에있는 모든 항목이 사용 된 것이 아니라면 교착 상태가 발생할 수 있습니다. 비슷하게 자식 프로세스가 비 데몬 (non-daemonic)이라면 비 데몬 (non-daemonic) 자식을 모두 참여 시키려고 할 때 부모 프로세스가 종료 될 때 정지 될 수 있습니다. 관리자를 사용하여 생성 된 대기열에는이 문제가 없습니다. 제대로 공유와

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

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

풀 프로세스를 생성합니다 :

전역 변수로 큐를 설정하고 초기화시 모든 프로세스를 설정하여 풀과 multiprocessing.Queue()를 사용하는 해결 방법은 다중 처리 .Queue() 객체가이 용도로 생성되지 않았다고 주장 할 수 있습니다.

한편 manager.Queue()는 함수의 일반적인 인수로 전달하여 풀 서브 프로세스간에 공유 될 수 있습니다.

제 생각에는 multiprocessing.Manager()를 사용하면 Queue()가 모든 경우에 문제가 없으며 덜 골칫거리입니다. 관리자를 사용하는 데는 몇 가지 단점이있을 수 있지만 잘 모릅니다.