2016-12-22 2 views
0

저는 python2.7 다중 처리 모듈을 좀 더 편안하게 사용하려고합니다. 그래서 필자는 파일 이름과 원하는 수의 프로세스를 입력으로 사용하는 작은 스크립트를 작성한 다음 여러 프로세스를 시작하여 대기열의 각 파일 이름에 함수를 적용합니다. 그것은 다음과 같습니다 : 큐에있는 모든 개체가 사용되는 때까지파이썬 다중 처리 스크립트가 종료되지 않습니다.

import multiprocessing, argparse, sys 
from argparse import RawTextHelpFormatter 

def parse_arguments(): 
    descr='%r\n\nTest different functions of multiprocessing module\n%r' % ('_'*80, '_'*80) 
    parser=argparse.ArgumentParser(description=descr.replace("'", ""), formatter_class=RawTextHelpFormatter) 
    parser.add_argument('-f', '--files', help='list of filenames', required=True, nargs='+') 
    parser.add_argument('-p', '--processes', help='number of processes for script', default=1, type=int) 
    args=parser.parse_args() 
    return args 

def print_names(name): 
    print name 


###MAIN### 

if __name__=='__main__': 
    args=parse_arguments() 
    q=multiprocessing.Queue() 
    procs=args.processes 
    proc_num=0 
    for name in args.files: 
     q.put(name) 
    while q.qsize()!=0: 
     for x in xrange(procs): 
      proc_num+=1 
      file_name=q.get() 
      print 'Starting process %d' % proc_num 
      p=multiprocessing.Process(target=print_names, args=(file_name,)) 
      p.start() 
      p.join() 
      print 'Process %d finished' % proc_num 

스크립트는 잘 작동하고 새로운 프로세스를 오래된 프로세스가 완료 할 때마다 (나는 그것이 어떻게 작동하는지 그 생각?)이 시작됩니다. 그러나 스크립트는 대기열을 완료 한 후에 종료하지 않고 유휴 상태로 있으며 Ctrl+C을 사용하여 종료해야합니다. 여기에 어떤 문제가 있습니까?

답변 해 주셔서 감사합니다.

+0

? 자식 프로세스간에 공유되지 않는다면,'args.files'를 통해 반복 할 수도 있습니다. – cdarke

+0

이전에 'multiprocessing.Pool()'을 사용하여 파일 목록을 반복하여 여러 프로세스를 생성했습니다. 그러나 대용량 파일 목록의 경우 최종적으로 프로세스 수가 줄어들 었는데, 그 이유는 파일이 작을 때 일부 프로세스가 작업 목록에서 더 빨리 완료되기 때문입니다. 여기에서는 프로세스가 끝날 때마다 새 파일로 새 프로세스를 시작하고 프로그램 속도를 최적화하기 위해 큐를 사용하려고합니다. –

답변

1

마치 몇 가지를 혼합 한 것처럼 보입니다. 프로세스를 생성하고 작업을 수행 한 후 다음 반복에서 새 프로세스를 시작하기 전에 프로세스가 종료 될 때까지 기다립니다. 이 접근법을 사용하면 순차적 처리가 어려워지며 여기에는 실제 다중 처리가 수행되지 않습니다.

어쩌면 당신은 출발점으로이 먹고 싶어 : 왜 큐를 사용하는

import sys 
import os 
import time 
import multiprocessing as mp 

def work_work(q): 
    # Draw work from the queue 
    item = q.get() 
    while item: 
     # Print own process id and the item drawn from the queue 
     print(os.getpid(), item) 
     # Sleep is only for demonstration here. Usually, you 
     # do not want to use this! In this case, it gives the processes 
     # the chance to "work" in parallel, otherwise one process 
     # would have finished the entire queue before a second one 
     # could be spawned, because this work is quickly done. 
     time.sleep(0.1) 
     # Draw new work 
     item = q.get() 

if __name__=='__main__': 
    nproc = 2 # Number of processes to be used 
    procs = [] # List to keep track of all processes 

    work = [chr(i + 65) for i in range(5)] 
    q = mp.Queue() # Create a queue... 
    for w in work: 
     q.put(w) # ...and fill it with some work. 

    for _ in range(nproc): 
     # Spawn new processes and pass each of them a reference 
     # to the queue where they can pull their work from. 
     procs.append(mp.Process(target=work_work, args=(q,))) 
     # Start the process just created. 
     procs[-1].start() 

    for p in procs: 
     # Wait for all processes to finish their work. They only 
     # exit once the queue is empty. 
     p.join() 
+0

오, 네 말이 맞아, 나는 다중 처리가 전혀 안된다 .. –

+0

좋아, 나는 목록에 프로세스를 넣고 모든 작업을 마쳤을 때 실제로 어떻게하고 싶은지를 본다. 작은 질문 : 대기열의 항목으로 프로세스가 완료되었지만 대기열이 여전히 가득차면 대기열이 비어있을 때까지 동일한 수의 프로세스로 프로그램을 계속 실행하기 때문에 다른 대기열을 선택합니까? –

+0

네, 그게 바로 여기서 일어날 일입니다. – jbndlr

관련 문제