您的位置:

Python进程池详解

一、概述

Python进程池是一种用于在Python中创建多个线程并执行并发任务的机制。主线程可以创建一组子线程,将多个任务分发给它们去完成,然后等待它们完成,最后再将所有的结果进行聚合。

与线程池相比,进程池更适合计算密集型任务,并且通常可以使程序性能得到更好的提升。因为进程池中的每个进程都运行在自己的进程空间中,互不干扰。这对于计算密集型任务来说非常适合。

二、进程池基本用法

Python内置了multiprocessing模块,它提供了一个Pool类来实现进程池的操作。


import multiprocessing as mp

def task(num):
    return num * num

if __name__ == "__main__":
    pool = mp.Pool()
    res = pool.map(task, [1, 2, 3, 4, 5])
    print(res)

以上代码中,首先导入multiprocessing模块。在task函数中,我们定义了一个简单的任务(计算输入值的平方)。

在主程序中,我们创建了一个进程池,并用map()方法将任务分配给进程池中的进程来处理。map()方法将任务列表中的每个元素作为参数传递给任务函数,进程池返回一个与任务列表等长的结果列表。

运行该程序,可以得到如下的输出:


[1, 4, 9, 16, 25]

三、常用进程池方法

1. apply()

apply()方法用于向进程池提交一个任务,并等待任务完成并返回结果。


import multiprocessing as mp

def task(num):
    return num * num

if __name__ == "__main__":
    pool = mp.Pool()
    res = pool.apply(task, args=(5,))
    print(res)

以上代码中,我们用apply()方法向进程池提交了一个任务,并传入任务函数需要的参数,pool.apply()方法会阻塞进程,直到该任务完成并返回结果。

运行该程序,可以得到如下的输出:


25

2. apply_async()

apply_async()方法用于向进程池提交一个异步任务(即无需等待任务完成),将任务加入到进程池的队列里,并立即返回一个AsyncResult对象。


import multiprocessing as mp

def task(num):
    return num * num

if __name__ == "__main__":
    pool = mp.Pool()
    res = pool.apply_async(task, args=(5,))
    print(res.get())

在以上代码中,我们用apply_async()方法向进程池提交任务,并传入任务函数需要的参数。apply_async()方法会立即返回一个AsyncResult对象,可以使用.get()方法在需要结果时获取结果。

运行该程序,可以得到如下的输出:


25

3. map()

map()方法用于向进程池提交多个任务,并等待所有任务完成并返回结果。


import multiprocessing as mp

def task(num):
    return num * num

if __name__ == "__main__":
    pool = mp.Pool()
    res = pool.map(task, [1, 2, 3, 4, 5])
    print(res)

在以上代码中,我们用map()方法向进程池提交了多个任务,并将任务结果存储在一个列表中。

运行该程序,可以得到如下的输出:


[1, 4, 9, 16, 25]

4. map_async()

map_async()方法用于向进程池提交多个异步任务(即无需等待任务完成),并立即返回一个AsyncResult对象。


import multiprocessing as mp

def task(num):
    return num * num

if __name__ == "__main__":
    pool = mp.Pool()
    res = pool.map_async(task, [1, 2, 3, 4, 5])
    print(res.get())

在以上代码中,我们用map_async()方法向进程池提交了多个异步任务,并使用.get()方法在需要结果时获取结果。

运行该程序,可以得到如下的输出:


[1, 4, 9, 16, 25]

5. close()和join()

close()方法用于向进程池发送一个停止信号,表示不再接受新任务。而join()方法则用于等待进程池中的所有任务完成。


import multiprocessing as mp

def task(num):
    return num * num

if __name__ == "__main__":
    pool = mp.Pool()
    res = pool.map_async(task, [1, 2, 3, 4, 5])
    pool.close()
    pool.join()
    print(res.get())

在以上代码中,我们用close()方法发送停止信号,并用join()方法等待所有任务完成。

运行该程序,可以得到如下的输出:


[1, 4, 9, 16, 25]

四、其他注意事项

需要注意的是,当调用进程池的close()方法后,不能再向进程池中提交新的任务,否则会引发异常。此外,在使用进程池时,尽量避免使用全局变量,因为多个进程之间共享全局变量可能会导致不一致的结果。

五、总结

Python进程池是一种用于在Python中实现并发任务的机制。

在Python中,我们可以通过multiprocessing模块提供的Pool类来实现进程池。

进程池提供了多种方法来处理任务,包括apply()、apply_async()、map()、map_async()等。

在使用进程池时,需要注意不能再向进程池中提交新的任务,否则会引发异常。同时,需要避免使用全局变量,以防止出现不一致的结果。