Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 多处理从模块或类内启动,而不是从main()启动_Python_Multithreading_Multiprocessing - Fatal编程技术网

Python 多处理从模块或类内启动,而不是从main()启动

Python 多处理从模块或类内启动,而不是从main()启动,python,multithreading,multiprocessing,Python,Multithreading,Multiprocessing,我想使用Python的多处理单元来有效地利用多个cpu来加快我的处理速度 所有这些似乎都可以运行,但是我想从类内部,在程序深处的子模块中运行Pool.map(f[item,item])。原因是程序必须首先准备数据,并等待某些事件发生,然后才能处理任何内容 声明只有在语句中才能从运行。我不明白这有什么意义,但还是试了一下,就像这样: from multiprocessing import Pool class Foo(object): n = 1000000 def __init__(s

我想使用Python的多处理单元来有效地利用多个cpu来加快我的处理速度

所有这些似乎都可以运行,但是我想从类内部,在程序深处的子模块中运行
Pool.map(f[item,item])
。原因是程序必须首先准备数据,并等待某些事件发生,然后才能处理任何内容

声明只有在语句中才能从
运行。我不明白这有什么意义,但还是试了一下,就像这样:

from multiprocessing import Pool

class Foo(object):
  n = 1000000
  def __init__(self, x):
    self.x = x + 1
    pass

  def run(self):
    for i in range(1,self.n):
      self.x *= 1.0*i/self.x
    return self

class Bar(object):
    def __init__(self):
        pass

    def go_all(self):
        work = [Foo(i) for i in range(960)]
        def do(obj):
            return obj.run()

        p = Pool(16)
        finished_work = p.map(do, work)
        return

bar = Bar()
bar.go_all()
真的不行!我得到以下错误:

PicklingError:无法pickle:属性查找 内置。功能失败

我不太明白为什么,因为所有的东西似乎都是可以挑选的。我有以下问题:

  • 不在我的主程序中加入p.map行,这能起作用吗
  • 如果没有,是否可以将“主”程序称为子例程/模块,以使其仍能工作
  • 是否有一些简便的技巧可以从子模块循环回主程序并从那里运行它

  • 我使用的是Linux和Python 2.7,我相信您误解了文档。文档中说的就是要做到这一点:

    if __name__ == '__main__':
        bar = Bar()
        bar.go_all()
    
    因此,您的
    p.map
    行不需要位于“main function”或其他任何内容中。只有实际生成子流程的代码必须被“保护”。由于Windows操作系统的限制,这是不可避免的


    此外,传递给
    Pool.map
    的函数必须是可导入的(函数只需按其名称进行pickle处理,然后解释器必须能够导入它们以在传递给子流程时重建函数对象)。因此,您可能应该在全局级别移动
    do
    函数,以避免酸洗错误。

    ms windows上对
    多处理
    模块的额外限制源于它没有
    fork
    系统调用这一事实。在类似UNIX的操作系统上,
    fork
    创建进程的完美副本,并继续在父进程旁边运行该进程。它们之间唯一的区别是
    fork
    在父进程和子进程中返回不同的值

    在ms windows上,
    多处理
    需要使用本机方法启动进程来启动新的Python实例。然后需要将该Python实例置于与“父”进程相同的状态


    这意味着(除其他外)Python代码必须是可导入的,而不会产生像尝试启动另一个进程这样的副作用。因此使用
    如果uuuu name uuu=='uuuu main uuu'
    保护。

    我在Linux上,你是说在这种情况下它不需要在main中吗?@Bastiaan是的,Linux有
    fork
    ,它避免了重新导入主模块。您只需从多处理导入池编写一个示例脚本
    ,即可对其进行测试;def f(x):返回x+1;p=池();打印(p.map(f[1,2,3])
    (添加导入在linux上它可以精细打印
    [2,3,4]
    在Windows上它会引发异常)。这取决于。默认情况下,Linux上使用启动进程的
    fork
    方法。这没有适用于ms windows的额外限制。但是,如果您使用forkserver启动方法,则会受到与w.r.t.可导入性相同的限制。有关所有输入和输出,请参阅
    多处理
    文档。您指的是该模块的全局级别还是一直到主模块的级别?后者将非常不方便。在全球范围内的子模块工作!并不是说我理解它,。。但是现在它很好。@Bastiaan如果你有一个模块
    a
    ,它定义了一个函数
    def g():def():…
    你如何从
    a
    导入
    f
    ?你不能。在windows上,由于windows的基本限制,这就是python在执行传递给
    p.map
    的回调时所做的!函数按名称“pickle”,然后发送到子进程。因此,子流程只接收函数名和定义它的模块名,并将其导入,然后执行实际调用并返回结果。但要使其工作,回调必须是可导入的。