Python 进程池

208 阅读3分钟

Python 进程池使用手册

进程池(Process Pool)是Python中用于并行处理任务的一种机制,它通过同时运行多个进程来充分利用多核CPU的计算能力,从而加快任务执行速度。Python的multiprocessing模块提供了对进程池的支持,让并行编程变得更加简单和高效。

1. 安装与导入

Python标准库已经包含了multiprocessing模块,因此无需额外安装。你可以直接在代码中导入它:

import multiprocessing
from multiprocessing import Pool

2. 创建进程池

使用Pool类可以创建一个进程池。Pool类提供了多种方法来管理进程池中的进程。

创建进程池的基本语法

pool = Pool(processes=None, initializer=None, initargs=(), maxtasksperchild=None, context=None)
  • processes:指定进程池中进程的数量。如果为None,则使用os.cpu_count()返回的数量。
  • initializer:如果提供了这个参数,那么每个工作进程在启动时都会先调用这个initializer函数。
  • initargs:一个元组,用于传递给initializer函数的参数。
  • maxtasksperchild:每个工作进程在终止前可以完成的任务数。如果为None,则工作进程可以无限期地运行。
  • context:用于指定上下文(如multiprocessing.spawnmultiprocessing.fork等)。

示例

pool = Pool(processes=4)  # 创建一个包含4个进程的进程池

3. 使用进程池执行任务

进程池提供了多种方法来分配任务给进程池中的进程。

map 方法

map方法类似于内置的map函数,它会对输入的每一个元素应用指定的函数,并返回结果列表。

def my_function(x):
    return x * x

if __name__ == '__main__':
    with Pool(processes=4) as pool:
        results = pool.map(my_function, range(10))
    print(results)  # 输出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

apply 方法

apply方法用于将单个任务分配给进程池中的一个进程,并等待结果返回。它接受两个参数:要调用的函数和该函数的参数(元组形式)。

def my_function(x, y):
    return x + y

if __name__ == '__main__':
    with Pool(processes=4) as pool:
        result = pool.apply(my_function, (1, 2))
    print(result)  # 输出: 3

apply_async 方法

apply_async方法与apply方法类似,但它不会等待结果返回,而是立即返回一个AsyncResult对象,你可以通过该对象来获取结果。

def my_function(x, y):
    return x + y

if __name__ == '__main__':
    with Pool(processes=4) as pool:
        async_result = pool.apply_async(my_function, (1, 2))
        print(async_result.get())  # 输出: 3

starmap 方法

starmap方法类似于map方法,但它接受一个函数和一个包含多个参数元组的可迭代对象。

def my_function(x, y):
    return x * y

if __name__ == '__main__':
    with Pool(processes=4) as pool:
        results = pool.starmap(my_function, [(1, 2), (3, 4), (5, 6)])
    print(results)  # 输出: [2, 12, 30]

closejoin 方法

  • close():阻止更多的任务被提交到进程池。
  • join():等待进程池中的所有进程结束。
if __name__ == '__main__':
    pool = Pool(processes=4)
    try:
        results = pool.map(my_function, range(10))
    finally:
        pool.close()
        pool.join()

4. 注意事项

  • 在Windows系统上,由于fork机制不可用,multiprocessing模块会使用spawn来启动新进程。这意味着每个进程都会重新导入主模块,因此在使用进程池时,应当将进程池相关的代码放在if __name__ == '__main__':块中,以避免无限递归。
  • 进程池中的进程是独立的,它们不会共享全局变量(除非使用特定的同步机制)。
  • 合理设置进程池的大小,避免创建过多的进程导致系统资源耗尽。

5. 示例代码

下面是一个完整的示例代码,演示了如何使用进程池来计算一组数的平方:

import multiprocessing
from multiprocessing import Pool

def square(x):
    return x * x

if __name__ == '__main__':
    numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    with Pool(processes=4) as pool:
        results = pool.map(square, numbers)
    print(results)  # 输出: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

通过以上内容,你应该能够掌握Python进程池的基本使用方法,并能够在自己的项目中应用它来加速任务处理。