Python多处理:如何知道使用池或进程?

Python多处理:如何知道使用池或进程?,python,multiprocessing,threadpool,Python,Multiprocessing,Threadpool,所以我有一个我正在编写的算法,函数多进程应该调用另一个函数,CreateMatrixMp(),在有CPU的进程上并行调用。我以前从未做过多重处理,无法确定以下哪种方法更有效。在函数CreateMatrixMp()的上下文中使用的“高效”一词可能会被调用数千次。我已经阅读了python多处理模块的所有文档,并得出了以下两种可能性: 首先是使用池类: def MatrixHelper(self, args): return self.CreateMatrix(*args) def Mult

所以我有一个我正在编写的算法,函数
多进程
应该调用另一个函数,
CreateMatrixMp()
,在有CPU的进程上并行调用。我以前从未做过多重处理,无法确定以下哪种方法更有效。在函数
CreateMatrixMp()
的上下文中使用的“高效”一词可能会被调用数千次。我已经阅读了python
多处理模块的所有文档,并得出了以下两种可能性:

首先是使用
类:

def MatrixHelper(self, args):
    return self.CreateMatrix(*args)

def Multiprocess(self, sigmaI, sigmaX):

    cpus = mp.cpu_count()
    print('Number of cpu\'s to process WM: %d' % cpus)
    poolCount = cpus*2
    args = [(sigmaI, sigmaX, i) for i in range(self.numPixels)]

    pool = mp.Pool(processes = poolCount, maxtasksperchild= 2)
    tempData = pool.map(self.MatrixHelper, args)
    pool.close()
    pool.join()
def Multiprocess(self, sigmaI, sigmaX):

    cpus = mp.cpu_count()
    print('Number of cpu\'s to process WM: %d' % cpus)

    processes = [mp.Process(target = self.CreateMatrixMp, args = (sigmaI, sigmaX, i,)) for i in range(self.numPixels)]
    for p in processes:
        p.start()
    for p in processes:
        p.join()
接下来是使用
过程
类:

def MatrixHelper(self, args):
    return self.CreateMatrix(*args)

def Multiprocess(self, sigmaI, sigmaX):

    cpus = mp.cpu_count()
    print('Number of cpu\'s to process WM: %d' % cpus)
    poolCount = cpus*2
    args = [(sigmaI, sigmaX, i) for i in range(self.numPixels)]

    pool = mp.Pool(processes = poolCount, maxtasksperchild= 2)
    tempData = pool.map(self.MatrixHelper, args)
    pool.close()
    pool.join()
def Multiprocess(self, sigmaI, sigmaX):

    cpus = mp.cpu_count()
    print('Number of cpu\'s to process WM: %d' % cpus)

    processes = [mp.Process(target = self.CreateMatrixMp, args = (sigmaI, sigmaX, i,)) for i in range(self.numPixels)]
    for p in processes:
        p.start()
    for p in processes:
        p.join()
Pool
似乎是更好的选择。我已经读到它会减少开销。和<代码>进程<代码>不考虑计算机上的CPU数量。唯一的问题是,以这种方式使用
Pool
会给我带来一个又一个错误,每当我修复一个错误时,它下面就会有一个新的错误<代码>过程
似乎更容易实现,据我所知,它可能是更好的选择。你的经历告诉你什么


如果应该使用
Pool
,那么我选择
map()
对吗?最好维持秩序。我有
tempData=pool.map(…)
,因为
map
函数应该返回每个进程的结果列表。我不确定
Process
如何处理返回的数据

我认为
Pool
类通常更方便,但这取决于您希望结果有序还是无序

假设您要创建4个随机字符串(例如,。可以是随机用户ID生成器或其他):

在这里,顺序可能并不重要。我不确定是否有更好的方法,但如果我想按照调用函数的顺序跟踪结果,我通常会返回第一项ID为的元组,例如

# define a example function
def rand_string(length, pos, output):
    """ Generates a random string of numbers, lower- and uppercase chars. """
    rand_str = ''.join(random.choice(
                    string.ascii_lowercase
                    + string.ascii_uppercase
                    + string.digits)
                for i in range(length))
    output.put((pos, rand_str))

# Setup a list of processes that we want to run
processes = [mp.Process(target=rand_string, args=(5, x, output)) for x in range(4)]

print(processes)

# Output
# [(1, '5lUya'), (3, 'QQvLr'), (0, 'KAQo6'), (2, 'nj6Q0')]
下面让我们对结果进行排序:

results.sort()
results = [r[1] for r in results]
print(results)

# Output:
# ['KAQo6', '5lUya', 'nj6Q0', 'QQvLr']
台球课 现在来回答您的问题:这与
类有何不同? 您通常更喜欢
Pool.map
返回结果的有序列表,而不必经过创建元组和按ID排序的过程。因此,我认为这通常更有效

def cube(x):
    return x**3

pool = mp.Pool(processes=4)
results = pool.map(cube, range(1,7))
print(results)

# output:
# [1, 8, 27, 64, 125, 216]
同样,还有一种“应用”方法:

Pool.apply
Pool.map
都将锁定主程序,直到进程完成


现在,您还有
Pool.apply_async
Pool.map_async
,它们在进程完成后立即返回结果,这与上面的
进程
类基本类似。其优点可能是,它们为您提供了方便的
apply
map
功能,您可以通过Python内置的
apply
map
轻松实现这一点:

将pypeln作为pl导入
stage=pl.process.map(
CreateMatrixMp,
范围(自像素),
工人=池计数,
maxsize=2,
)
#在主流程中对其进行迭代
对于阶段中的x:
#代码
#或者将其转换为列表
数据=列表(阶段)

这似乎与Thanks@MartinAlderete我读过那篇文章。然而,我在这里提出了一些需要回答的不同问题。他使用两个目标函数,而我使用一个,他不传递参数,而我传递多个,他不必担心他的目标是一个实例方法,就像我的一样。到目前为止,我已经对此做了很多研究,
Pool
Process
在不同的环境下表现出不同的行为,当然,在某些情况下,一个会更好,而在其他情况下则不会。我认为开始一个新问题是合适的。谢谢你的回答。我在选择一个而不是另一个时主要考虑的是机器和处理器的数量。在池中,您可以将其设置为与CPU数量相同的进程。但是,通过使用
进程
,CPU的数量是不存在的。这件事会自己处理吗?通过使用
流程
,是否会导致花费稍多的时间?我想使用
Process
,而
Pool
的所有pickle错误让我感到非常困难,但是
Process
感觉不像
Pool
那么具体。我认为“Process”更像是一种“赤裸裸”的方法,据我所知,您必须手动管理它。当您生成一个进程但所有CPU都忙时,它将排队,直到CPU再次空闲。如果一次分派太多正在等待的进程,这可能是一个潜在的问题(如果数量“相对”大,则很容易耗尽系统的可用内存)。是的,在尝试使用
进程时内存是一个问题。我已将其用于
,感谢您的建议,我将此标记为已回答。