如何使用多进程池python

时间:2018-04-07 02:40:04

标签: python

如何在python中使用Multiprocess池从不同的类(不同的模块)调用方法?

我的目标是启动一个持续运行的流程,直到提供任务为止,一旦任务完成,它将再次返回等待模式。

下面是代码,其中有三个模块,Reader类是我的运行时任务,我将为ProcessExecutor提供执行读取器方法。 进程执行程序是进程池,它将在循环中继续,直到向其提供某个任务。

主要模块启动一切。

Module 1

class Reader(object):
    def __init__(self, message):
        self.message = message

    def reader(self):
        print self.message

Module 2


class ProcessExecutor():
    def run(self, queue):
        print 'Before while loop'
        while True:
            print 'Reached Run'
            try:
                pair = queue.get()
                print 'Running process'
                print pair
                func = pair.get('target')
                arguments = pair.get('args', None)
                if arguments is None:
                    func()
                else:
                    func(arguments)
                queue.task_done()
            except Exception:
                print Exception.message



main Module
from process_helper import ProcessExecutor
from reader import Reader
import multiprocessing
import Queue

if __name__=='__main__':
    queue = Queue.Queue()
    myReader = Reader('Hi')
    ps = ProcessExecutor()
    pool = multiprocessing.Pool(2)
    pool.apply_async(ps.run, args=(queue, ))
    param = {'target': myReader.reader}
    queue.put(param)
  

执行的代码没有任何错误:C:\ Python27 \ python.exe   C:/Users/PycharmProjects/untitled1/main/main.py

     

处理完成,退出代码为0

代码被执行但它从未到达run方法。我不确定是否可以使用多进程调用不同类的方法

我尝试了apply_async,map,apply但是没有一个正在运行。 在线搜索的所有示例都是从实现main方法的脚本调用目标方法。 我正在使用python 2.7 请帮忙。

1 个答案:

答案 0 :(得分:0)

你的第一个问题是你只需退出而不等任何事情。您有一个Pool,一个Queue和一个AsyncResult,但您只需忽略所有这些内容,并在创建后立即退出。你应该只能等待AsyncResult(之后,没有更多的工作要做了,所以谁关心你放弃了什么),除了你的事实尝试使用Queue.task_done,如果没有另一方Queue.join则没有任何意义,所以你也需要等待。

您的第二个问题是您正在使用Queue模块中的Queue,而不是multiprocessing模块中的Queuetask_done模块仅适用于同一进程中的线程。

此外,您无法在普通Queue上致电JoinableQueue;这只是dill子类的一种方法。

一旦你达到了池试图实际运行任务的程度,你就会遇到绑定方法无法被腌制的问题,除非你为它们编写了一个pickler。这样做很痛苦,尽管这是正确的方法。传统的解决方法 - hacky和俗气,但每个人都这样做,而且它的工作原理是将每个要调用的方法包装在顶级函数中。现代解决方案是使用第三方cloudpicklemultiprocessing库,它们知道如何挑选绑定方法,以及如何挂钩from process_helper import ProcessExecutor from reader import Reader import multiprocessing def call_run(ps): ps.run(queue) def call_reader(reader): return reader.reader() if __name__=='__main__': queue = multiprocessing.JoinableQueue() myReader = Reader('Hi') ps = ProcessExecutor() pool = multiprocessing.Pool(2) res = pool.apply_async(call_run, args=(ps,)) param = {'target': call_reader, 'args': myReader} queue.put(param) print res.get() queue.join() 。你一定要看看它们。但是,为了简单起见,我将向您展示解决方法。

请注意,因为您已经创建了一个额外的队列来传递方法,除了池中内置的方法之外,您还需要两个目标的解决方法。

修复了这些问题后,您的代码如下所示:

ProcessReader

您的Pool还有其他错误,但我不打算为您调试所有内容。这可以让您超越最初的障碍,并显示您询问的具体问题的答案。此外,我不确定所有代码的重点是什么。您似乎试图替换Pool已经在ProcessExecutor之上执行的操作,只是以更复杂但功能更弱的方式,但我并不完全确定。

与此同时,这是一个程序,只需丢弃from reader import Reader import multiprocessing def call_reader(reader): return reader.reader() if __name__=='__main__': myReader = Reader('Hi') pool = multiprocessing.Pool(2) res = pool.apply_async(call_reader, args=(myReader,)) print res.get() 以及随之而来的所有内容,即可完成我认为您想要的,没有问题:

{{1}}