Python如何在类内部进行多处理?

Python如何在类内部进行多处理?,python,multiprocessing,Python,Multiprocessing,我的代码结构如下所示: Class A: def __init__(self): processes = [] for i in range(1000): p = Process(target=self.RunProcess, args=i) processes.append[p] # Start all processes [x.start() for x in processes] def RunProcess(self,

我的代码结构如下所示:

Class A:
  def __init__(self):
    processes = []
    for i in range(1000):
      p = Process(target=self.RunProcess, args=i)
      processes.append[p]

    # Start all processes
    [x.start() for x in processes]

  def RunProcess(self, i):
    do something with i...
class A:
    def __init__(self, ...):
        pass

    def compute(self):
        procs = [Process(self.run, ...) for ... in ...]
        [p.start() for p in procs]
        [p.join() for p in procs]

    def run(self, ...):
        pass

pool = A(...)
pool.compute()
主脚本:

myA = A()
我似乎无法让它运行。我收到一个运行时错误“试图在 当前进程已完成其引导阶段。

我如何让多个处理为此工作?如果我使用线程,它的工作很好,但它是缓慢的顺序。。。我还担心多重处理也会很慢,因为创建过程需要更长的时间


有什么好的建议吗?非常感谢。

一个切实可行的方法是将你的班级进行分类,例如:

Class A:
  def __init__(self):
    processes = []
    for i in range(1000):
      p = Process(target=self.RunProcess, args=i)
      processes.append[p]

    # Start all processes
    [x.start() for x in processes]

  def RunProcess(self, i):
    do something with i...
class A:
    def __init__(self, ...):
        pass

    def compute(self):
        procs = [Process(self.run, ...) for ... in ...]
        [p.start() for p in procs]
        [p.join() for p in procs]

    def run(self, ...):
        pass

pool = A(...)
pool.compute()
当您在
\uuuu init\uuuu
内部分叉一个进程时,类实例
self
可能不会完全初始化,因此要求子进程执行
self.run
是很奇怪的,尽管从技术上讲,是的,这是可能的

如果不是这样的话,那么听起来像是这个问题的一个例子:


我可以在您的代码中看到一些语法问题:

  • args
    过程中
    需要一个元组,如果传递一个整数,请将第5行更改为:

    p=Process(target=self.RunProcess,args=(i,)

  • list.append
    是一个方法,传递给它的参数应包含在
    ()
    中,而不是
    []
    ,请将第6行更改为:

    processs.append(p)

正如@qarma指出的,在类构造函数中启动进程不是一个好的实践。我将按如下方式构造代码(改编您的示例):


使用
池应该可以简化事情。就速度而言,启动进程确实需要时间。但是,使用
而不是运行
进程
njobs
,应该尽可能快地让它与进程一起运行。
(如下所用)的默认设置是使用可用进程的最大数量(即您拥有的CPU数量),并在作业完成后立即将新作业分配给工作人员。您将无法获得
njobs
-方式的并行性,但您将获得CPU在不过度订购处理器的情况下可以处理的尽可能多的并行性。我使用的是
pathos
,它有一个分支
多处理
,因为它比标准的
多处理
更健壮……而且,我也是作者。但是您可能可以使用
多处理
来实现这一点

>>> from pathos.multiprocessing import ProcessingPool as Pool
>>> class A(object):
...   def __init__(self, njobs=1000):
...     self.map = Pool().map
...     self.njobs = njobs
...     self.start()
...   def start(self):
...     self.result = self.map(self.RunProcess, range(self.njobs))
...     return self.result
...   def RunProcess(self, i):
...     return i*i
... 
>>> myA = A()
>>> myA.result[:11]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>> myA.njobs = 3
>>> myA.start()  
[0, 1, 4]
\uuu init\uuu
内部启动
池是一种有点奇怪的设计。但是如果您想这样做,您必须从类似于
self.result
…的内容中获取结果,并且您可以使用
self.start
进行后续调用


获取
pathos
此处:

这将返回cPickle.PicklingError:无法pickle:属性查找内置函数失败。有什么想法吗?@boson:这是什么?正是我上面发布的代码?因为,如果您安装了
dill
,它就不应该使用
cPickle
。很抱歉,内容含糊不清。我正在运行一个类似类型的程序,在类函数中使用多处理。我刚刚确认我确实有dill,所以我不确定为什么要调用cPickle。@boson:你应该在so上创建一个单独的帖子,或者在multiprocess的github上创建一个票证。@MikeMcKerns。Mike,为什么在
运行过程中调用函数不起作用<代码>def RunProcess(self,i):a=sum\u add(i)
。。。然后
def sum\u add(i):返回i+1
。。我得到
名称错误:未定义全局名称“sum\u add”
。sum_add与单独的函数位于同一个文件中。我如何调用该函数?我尝试了
global sum\u add
。如果我将其作为
self.sum\u add
移动到类中,我可以调用
sum\u add
,但不能在类之外。是否可以限制并发进程的数量?@akozi,是的。如果使用进程池,则并发进程的最大数量将受到池数量的限制workers@HaleemurAli,在本例中:假设方法
do\u something
返回一个值,我如何收集结果?为什么不抛出错误,因为它无法pickle函数?我认为绑定函数不能被酸洗。