Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.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 pathos.multiprocessing ProcessingPool。为什么池交换信息?_Python_Multiprocessing_Pathos - Fatal编程技术网

Python pathos.multiprocessing ProcessingPool。为什么池交换信息?

Python pathos.multiprocessing ProcessingPool。为什么池交换信息?,python,multiprocessing,pathos,Python,Multiprocessing,Pathos,简介 我有大量数据,需要进行具体计算。不幸的是,如果我一个接一个地进行计算,整个过程将花费一天的时间。这就是为什么我在一台有32个CPU的机器上使用paths.multiprocessing ProcessingPool。这样,整个过程大约需要30分钟 问题 预期的行为是所有计算并行运行,并且彼此完全独立。我注意到,对于少量计算(例如40),这是正确的,但如果我将数字增加到90,数据会混合。这些过程似乎是相互“交流”的……换句话说,它们可以访问相同的变量 问题 知道发生了什么吗 有用链接: 代码

简介

我有大量数据,需要进行具体计算。不幸的是,如果我一个接一个地进行计算,整个过程将花费一天的时间。这就是为什么我在一台有32个CPU的机器上使用paths.multiprocessing ProcessingPool。这样,整个过程大约需要30分钟

问题

预期的行为是所有计算并行运行,并且彼此完全独立。我注意到,对于少量计算(例如40),这是正确的,但如果我将数字增加到90,数据会混合。这些过程似乎是相互“交流”的……换句话说,它们可以访问相同的变量

问题

知道发生了什么吗

有用链接:

代码

下面的代码是我机器上的简化版本,但想法是一样的。下面是代码:

from pathos.multiprocessing import ProcessingPool, cpu_count

class TestMultiprocessing:
    def __init__(self):
        self.number = 0

    def do_something(self, args):
        for arg in args:
            self.number += arg
        return self.number

    def run(self):
        # Generate a big list
        l = []
        for i in range(0, 100):
            l.append([1,2,3])

        pool = ProcessingPool(cpu_count())
        results = pool.imap(self.do_something, l)
        pool.close()
        pool.join()
        pool.clear()
        results = list(results)

        for result in results:
            print(result)

tm = TestMultiprocessing()
tm.run()
更新

我不能展示示例代码,因为它是保密的,但我可以对代码的工作原理做一个简短的解释

有一个CSV文件,其中包含数千行数据(~80000行)。我编写的代码必须运行800个任务,每个任务执行特定的计算,从CSV文件中获取数据

机器有N个CPU,因此Pathos将所有800个任务分解为M个组,每个组包含N个任务(如果CPU的数量为偶数M*N=800)。Pathos创建N个并行执行所需计算的池。当计算完成时,每个池生成一个字典列表,并继续执行下一组任务-重复该过程M次

列表中的每个字典都包含一个与任务编号相对应的唯一键,该编号可以是1到800。通过这种方式,我可以检查池X是否生成与任务X相关的字典(例如103)。期望是池X生成的结果只包含键X

值得一提的是,上述过程消耗了机器的大部分内存

在对生成的结果进行详细观察后,我注意到以下几点。如果我运行N个任务(例如,4个任务对应一台有4个CPU的机器),则每个字典列表都包含对应于特定任务的键。例如,池X生成一个带有键X的字典列表

但是,如果我运行的任务超过N个,则与大于N的任务对应的字典将包含来自以前任务的数据。例如,池Y生成一个带有键Y、X等的字典列表

我的结论是,pool X不会从以前的计算中清除数据(内存),而下一个任务将从以前的计算中继承数据

解决方案

尽管我使用了pool.clear(),但这并不能帮助我解决问题。我找到的临时解决方案如下

我“手动”将任务分解为多个组

import numpy as np
import math

# Get the number of CPUs
cpus = cpu_count()

# Check how many groups of tasks we have to run
chunks = math.ceil(len(l)/cpus)

# Break down the list of tasks to chunks/groups
l_chunks = np.array_split(l, chunks)

# Loop the chunks
for l_chunk in l_chunks:
    pool = ProcessingPool(cpus)
    results = pool.imap(self.do_something, l_chunk.tolist())
    pool.close()
    pool.join()
    pool.clear()
    results = list(results)
    
    for result in results:
        print(result)

这就解决了我的问题。

好吧,你是在多进程分叉之前初始化类来使用共享状态的……你说进程是通信的。展示你为什么这么想。换句话说,做一个适当的(顺便问一下,你需要
pathos
而不是内置的
multiprocessing
包,有什么理由吗?@AKX我应该做什么更改来避免共享状态?谢谢我之所以使用pathos是因为我对pickle有问题。我得想想到底是什么问题。“那是很久以前的事了。”物理学家,我不能举出一个例子,但我可以解释。有一个包含几千行数据的CSV文件。我并行运行大约800个任务。每个任务从CSV文件加载数据并执行不同的操作。每个完成的任务都会生成一个字典列表。每个字典都包含作为计算结果的数据。此外,字典还包含一个唯一的键,用于标识执行计算的过程。期望pool X生成字典列表,每个字典都有键X。如果我运行少量任务,这是真的。