Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/343.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 多处理池的奇怪行为.map_Python_Multiprocessing_Pool - Fatal编程技术网

Python 多处理池的奇怪行为.map

Python 多处理池的奇怪行为.map,python,multiprocessing,pool,Python,Multiprocessing,Pool,在使用pool.map调用方法函数时,我观察到一种非常奇怪的行为。 只有一个进程,其行为与简单的for循环不同,我们在if not self.seeded:块中输入了几次,而我们不应该这样做。 以下是代码和输出: 导入操作系统 来自多处理导入池 类MyClassobject: 定义初始自我: self.seeded=False 调用MyClass的printConstructor def fself,i: printf打电话给我 如果不是自种子: printPID:{},idself.seed:

在使用pool.map调用方法函数时,我观察到一种非常奇怪的行为。 只有一个进程,其行为与简单的for循环不同,我们在if not self.seeded:块中输入了几次,而我们不应该这样做。 以下是代码和输出:

导入操作系统 来自多处理导入池 类MyClassobject: 定义初始自我: self.seeded=False 调用MyClass的printConstructor def fself,i: printf打电话给我 如果不是自种子: printPID:{},idself.seed:{},self.seed:{}.formatos.getpid,idself.seed,self.seed self.seeded=True def multi_call_pool_mapself: PoolProcess=1作为池时: 使用{}进程打印多个调用池映射…格式化池。\进程 游泳池,mapself.f,范围10 def multi_call_for_loopself: 为循环打印多个调用。。。 列表_res=[] 对于范围10中的i: 列表_res.appendself.fi 如果uuuu name uuuuu==\uuuuuuuu main\uuuuuuuu: MyClass.multi\u调用\u池\u映射 产出:

Constructor of MyClass called
multi_call_pool_map with 1 processes...
f called with 0
PID : 18248, id(self.seeded) : 1864747472, self.seeded : False
f called with 1
f called with 2
f called with 3
PID : 18248, id(self.seeded) : 1864747472, self.seeded : False
f called with 4
f called with 5
f called with 6
PID : 18248, id(self.seeded) : 1864747472, self.seeded : False
f called with 7
f called with 8
f called with 9
PID : 18248, id(self.seeded) : 1864747472, self.seeded : False
Constructor of MyClass called
multi_call_for_loop ...
f called with 0
PID : 15840, id(self.seeded) : 1864747472, self.seeded : False
f called with 1
f called with 2
f called with 3
f called with 4
f called with 5
f called with 6
f called with 7
f called with 8
f called with 9
对于for循环:

如果uuuu name uuuuu==\uuuuuuuu main\uuuuuuuu: MyClass.multi\u调用\u for\u循环 产出:

Constructor of MyClass called
multi_call_pool_map with 1 processes...
f called with 0
PID : 18248, id(self.seeded) : 1864747472, self.seeded : False
f called with 1
f called with 2
f called with 3
PID : 18248, id(self.seeded) : 1864747472, self.seeded : False
f called with 4
f called with 5
f called with 6
PID : 18248, id(self.seeded) : 1864747472, self.seeded : False
f called with 7
f called with 8
f called with 9
PID : 18248, id(self.seeded) : 1864747472, self.seeded : False
Constructor of MyClass called
multi_call_for_loop ...
f called with 0
PID : 15840, id(self.seeded) : 1864747472, self.seeded : False
f called with 1
f called with 2
f called with 3
f called with 4
f called with 5
f called with 6
f called with 7
f called with 8
f called with 9
我们如何解释pool.map第一个案例的行为?我不明白为什么我们在if块中输入多次,因为self.seeded仅在构造函数中设置为False,并且构造函数只调用一次。。。
我有Python 3.6.8

当运行代码并在f中打印self时,我们可以看到,在每次输入if子句之前,实例实际上会发生变化:

def fself,i: printf打电话给我,self是,self 如果不是自种子: printPID:{},idself.seed:{},self.seed:{}.formatos.getpid,idself.seed,self.seed self.seeded=True 这将产生:

Constructor of MyClass called
multi_call_pool_map with 1 processes...
f called with 0 self is <__main__.MyClass object at 0x7f30cd592b38>
PID : 22879, id(self.seeded) : 10744096, self.seeded : False
f called with 1 self is <__main__.MyClass object at 0x7f30cd592b38>
f called with 2 self is <__main__.MyClass object at 0x7f30cd592b38>
f called with 3 self is <__main__.MyClass object at 0x7f30cd592b00>
PID : 22879, id(self.seeded) : 10744096, self.seeded : False
f called with 4 self is <__main__.MyClass object at 0x7f30cd592b00>
f called with 5 self is <__main__.MyClass object at 0x7f30cd592b00>
f called with 6 self is <__main__.MyClass object at 0x7f30cd592ac8>
PID : 22879, id(self.seeded) : 10744096, self.seeded : False
f called with 7 self is <__main__.MyClass object at 0x7f30cd592ac8>
f called with 8 self is <__main__.MyClass object at 0x7f30cd592ac8>
f called with 9 self is <__main__.MyClass object at 0x7f30cd592a90>
PID : 22879, id(self.seeded) : 10744096, self.seeded : False
Constructor of MyClass called
multi_call_pool_map with 1 processes...
f called with 0 self is <__main__.MyClass object at 0x7fd175093b00>
PID : 22972, id(self.seeded) : 10744096, self.seeded : False
f called with 1 self is <__main__.MyClass object at 0x7fd175093b00>
f called with 2 self is <__main__.MyClass object at 0x7fd175093b00>
f called with 3 self is <__main__.MyClass object at 0x7fd175093b00>
f called with 4 self is <__main__.MyClass object at 0x7fd175093b00>
f called with 5 self is <__main__.MyClass object at 0x7fd175093b00>
f called with 6 self is <__main__.MyClass object at 0x7fd175093b00>
f called with 7 self is <__main__.MyClass object at 0x7fd175093b00>
f called with 8 self is <__main__.MyClass object at 0x7fd175093b00>
f called with 9 self is <__main__.MyClass object at 0x7fd175093b00>
这将产生:

Constructor of MyClass called
multi_call_pool_map with 1 processes...
f called with 0 self is <__main__.MyClass object at 0x7f30cd592b38>
PID : 22879, id(self.seeded) : 10744096, self.seeded : False
f called with 1 self is <__main__.MyClass object at 0x7f30cd592b38>
f called with 2 self is <__main__.MyClass object at 0x7f30cd592b38>
f called with 3 self is <__main__.MyClass object at 0x7f30cd592b00>
PID : 22879, id(self.seeded) : 10744096, self.seeded : False
f called with 4 self is <__main__.MyClass object at 0x7f30cd592b00>
f called with 5 self is <__main__.MyClass object at 0x7f30cd592b00>
f called with 6 self is <__main__.MyClass object at 0x7f30cd592ac8>
PID : 22879, id(self.seeded) : 10744096, self.seeded : False
f called with 7 self is <__main__.MyClass object at 0x7f30cd592ac8>
f called with 8 self is <__main__.MyClass object at 0x7f30cd592ac8>
f called with 9 self is <__main__.MyClass object at 0x7f30cd592a90>
PID : 22879, id(self.seeded) : 10744096, self.seeded : False
Constructor of MyClass called
multi_call_pool_map with 1 processes...
f called with 0 self is <__main__.MyClass object at 0x7fd175093b00>
PID : 22972, id(self.seeded) : 10744096, self.seeded : False
f called with 1 self is <__main__.MyClass object at 0x7fd175093b00>
f called with 2 self is <__main__.MyClass object at 0x7fd175093b00>
f called with 3 self is <__main__.MyClass object at 0x7fd175093b00>
f called with 4 self is <__main__.MyClass object at 0x7fd175093b00>
f called with 5 self is <__main__.MyClass object at 0x7fd175093b00>
f called with 6 self is <__main__.MyClass object at 0x7fd175093b00>
f called with 7 self is <__main__.MyClass object at 0x7fd175093b00>
f called with 8 self is <__main__.MyClass object at 0x7fd175093b00>
f called with 9 self is <__main__.MyClass object at 0x7fd175093b00>
发生这种情况的确切原因是一个非常详细的实现细节,与多进程如何在同一池中的进程之间共享数据有关


恐怕我没有足够的资格回答这在内部是如何工作的以及为什么工作的。

当您对Pool.map使用实例方法时,对象实例的副本会在pickle模块的帮助下发送给工作进程。您的结果显示了map如何在块中工作,并且在每个块的开始处从pickle表单重新加载对象实例。加载pickle不会调用_init


有关发动机罩下的更多说明,请参阅。

感谢您的快速响应。尽管有多个实例,但构造函数只被调用一次,这一事实有点令人困惑。为什么idself.seeded对于所有不同的实例都是一样的?我试图在网上找到一篇关于这个的简单文章,但我找到的只是关于用法而不是内部细节,我担心这取决于你想做什么,但是使用的是来自多处理的.dummy导入池,这是不一样的!Google multiprocessing vs multithreading您可以立即获得所需的行为。这是因为池对您的输入进行分块的方式。设置的chunksize将为3,在此处生成[3,3,3,1]个块。你可以在我的答案中用calc_chunksize来计算。