многопроцессорная подсистема python.Process

Я новичок в объектно-ориентированном python, и я переписываю существующее приложение как объектно-ориентированную версию, потому что теперь разработчики расширяются, а мой код становится не поддающимся проверке.

Обычно я использую многопроцессорные очереди, но я нашел в этом примере http://www.doughellmann.com/PyMOTW/multiprocessing/basics.html, что я могу подклассы multiprocessing.Process поэтому я думаю, что это хорошая идея, и я написал класс для тестирования, как это:

код:

 from multiprocessing import Process class Processor(Process): def return_name(self): return "Process %s" % self.name def run(self): return self.return_name() processes = [] if __name__ == "__main__": for i in range(0,5): p=Processor() processes.append(p) p.start() for p in processes: p.join() 

Однако я не могу вернуть значения, как я могу использовать очереди таким образом?

EDIT: Я хочу получить возвращаемое значение и подумать, куда положить Queues() .

4 Solutions collect form web for “многопроцессорная подсистема python.Process”

Подсекция multiprocessing.Process Процесс:

Однако я не могу вернуть значения, как я могу использовать очереди таким образом?

Для получения результатов требуется Queue() Пример использования multiprocessing.Process подкласса. Процесс следует …

 from multiprocessing import Process, Queue class Processor(Process): def __init__(self, queue, idx, **kwargs): super(Processor, self).__init__() self.queue = queue self.idx = idx self.kwargs = kwargs def run(self): """Build some CPU-intensive tasks to run via multiprocessing here.""" hash(self.kwargs) # Shameless usage of CPU for no gain... ## Return some information back through multiprocessing.Queue ## NOTE: self.name is an attribute of multiprocessing.Process self.queue.put("Process idx={0} is called '{1}'".format(self.idx, self.name)) if __name__ == "__main__": NUMBER_OF_PROCESSES = 5 ## Create a list to hold running Processor object instances... processes = list() q = Queue() # Build a single queue to send to all process objects... for i in range(0, NUMBER_OF_PROCESSES): p=Processor(queue=q, idx=i) p.start() processes.append(p) # Incorporating ideas from this answer, below... # https://stackoverflow.com/a/42137966/667301 [proc.join() for proc in processes] while not q.empty(): print "RESULT: {0}".format(q.get()) # get results from the queue... 

На моей машине это приводит к …

 $ python test.py RESULT: Process idx=0 is called 'Processor-1' RESULT: Process idx=4 is called 'Processor-5' RESULT: Process idx=3 is called 'Processor-4' RESULT: Process idx=1 is called 'Processor-2' RESULT: Process idx=2 is called 'Processor-3' $ 

Использование multiprocessing.Pool :

FWIW, один из недостатков, который я нашел для подклассификации multiprocessing.Process Процесс заключается в том, что вы не можете использовать все встроенные преимущества multiprocessing.Pool Pool дает вам очень хороший API, если вам не нужен ваш код производителя и потребителя, чтобы разговаривать друг с другом через очередь.

Вы можете сделать много всего с некоторыми значениями возвращаемого объявления … в следующем примере я использую dict() для инкапсуляции входных и выходных значений из pool_job()

 from multiprocessing import Pool def pool_job(input_val=0): # FYI, multiprocessing.Pool can't guarantee that it keeps inputs ordered correctly # dict format is {input: output}... return {'pool_job(input_val={0})'.format(input_val): int(input_val)*12} pool = Pool(5) # Use 5 multiprocessing processes to handle jobs... results = pool.map(pool_job, xrange(0, 12)) # map xrange(0, 12) into pool_job() print results 

Это приводит к:

 [ {'pool_job(input_val=0)': 0}, {'pool_job(input_val=1)': 12}, {'pool_job(input_val=2)': 24}, {'pool_job(input_val=3)': 36}, {'pool_job(input_val=4)': 48}, {'pool_job(input_val=5)': 60}, {'pool_job(input_val=6)': 72}, {'pool_job(input_val=7)': 84}, {'pool_job(input_val=8)': 96}, {'pool_job(input_val=9)': 108}, {'pool_job(input_val=10)': 120}, {'pool_job(input_val=11)': 132} ] 

Очевидно, что в pool_job() есть много других улучшений, таких как обработка ошибок, но это иллюстрирует pool_job() . FYI, этот ответ дает еще один пример использования multiprocessing.Pool .

Возвращаемое значение Process.run не денется. Вам нужно отправить их обратно в родительский процесс, например, используя multiprocessing.Queue Queue ( docs здесь ).

Большое спасибо всем.

Теперь вот как я это сделал 🙂

В этом примере я использую несколько queus, поскольку я не хочу связываться между каждым ohter, но только с родительским процессом.

 from multiprocessing import Process,Queue class Processor(Process): def __init__(self,queue): Process.__init__(self) self.que=queue def get_name(self): return "Process %s" % self.name def run(self): self.que.put(self.get_name()) if __name__ == "__main__": processes = [] for i in range(0,5): p=Processor(Queue()) processes.append(p) p.start() for p in processes: p.join() print p.que.get() 

Ответ Майка – лучший, но только для полноты. Я хочу упомянуть, что я предпочитаю собирать очередь из контекстов join поэтому последний бит будет выглядеть так:

 [proc.join() for proc in processes] # 1. join while not q.empty(): # 2. get the results print "RESULT: %s" % q.get() 
  • наследование объектов и вложенный cmd
  • Печать всех свойств класса Python
  • Создание списка объектов из списка списков
  • Как поймать любой метод, вызываемый объектом в python?
  • Функция супер () Python
  • Разница между объектом и экземпляром в python?
  • Может ли простая разница в именах переменных Python3 изменять способ запуска кода?
  • Понимание разницы между __getattr__ и __getattribute__
  • Python - лучший язык программирования в мире.