2016-12-22 6 views
0

Я пытаюсь получить немного больше комфорта с модулем многопроцессорности python2.7. Поэтому я написал небольшой скрипт, который принимает имена файлов и необходимое количество процессов в качестве входных данных, а затем запускает несколько процессов для применения функции к каждому имени файла в моей очереди. Это выглядит следующим образом:сценарий многопроцессорности python не выходит

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