在 Python 中,我们可以使用多进程(multiprocessing)模块来实现多个任务的并行处理。多进程可以充分利用多核 CPU,提高程序的执行效率。
为什么选择多进程?
Python的全局解释器锁(GIL)限制了同一时刻只有一个线程执行字节码,这会在 CPU 密集型任务中限制多线程的性能。而多进程的方式则能够在不同的进程中独立执行,也避免了 GIL 的影响,因此在处理 CPU 密集型任务时,多进程的效果会更佳。
基础示例
下面我们通过一个简单的示例来理解如何使用多进程模块。假设我们有一个函数 compute_square
,它计算一个数字的平方,我们希望并行计算多个数字的平方。
import multiprocessing
import time
def compute_square(n):
print(f'计算 {n} 的平方...')
time.sleep(2) # 模拟耗时操作
result = n * n
print(f'{n} 的平方是 {result}')
return result
if __name__ == '__main__':
numbers = [1, 2, 3, 4, 5] # 要计算平方的数字列表
# 创建进程列表
processes = []
# 启动多个进程
for number in numbers:
process = multiprocessing.Process(target=compute_square, args=(number,))
processes.append(process)
process.start() # 启动进程
# 等待所有进程结束
for process in processes:
process.join()
print('所有任务完成!')
代码解读
-
导入模块:我们导入了
multiprocessing
模块。 -
定义任务函数:
compute_square
函数用于计算数字的平方,并在控制台打印出结果。为了模拟耗时操作,我们使用time.sleep(2)
。 -
主程序:在
if __name__ == '__main__':
保护下,我们首先定义了一个数字列表numbers
。 -
创建和启动进程:我们循环遍历
numbers
列表,为每个数字创建一个新进程,通过Process
类来实例化进程对象,指定target
为任务函数,args
为传递给函数的参数。然后通过process.start()
方法启动进程。 -
等待进程结束:通过
process.join()
方法等待各个子进程完成,主进程会在此阻塞,直到所有子进程完成。
进程池
当需要处理的任务数量较多时,直接创建多个进程可能会导致系统资源的浪费。此时,我们可以使用进程池(Pool)来限制同时激活的进程数量,通常会带来更好的性能。
以下是使用进程池的示例:
import multiprocessing
import time
def compute_square(n):
print(f'计算 {n} 的平方...')
time.sleep(2)
return n * n
if __name__ == '__main__':
numbers = [1, 2, 3, 4, 5]
# 创建进程池,设定池中最多同时运行 3 个进程
with multiprocessing.Pool(processes=3) as pool:
results = pool.map(compute_square, numbers) # 使用 map 方法并行处理
print('所有任务完成!结果:', results)
在这个示例中,我们使用 Pool
类来创建进程池并通过 pool.map()
方法来并行运行 compute_square
函数并返回结果。
小结
通过以上示例,我们了解了 Python 中使用 multiprocessing
模块实现多任务并行处理的基本方法。对于 CPU 密集型任务,多进程通常比多线程表现更好。借助进程池可以更高效地管理系统资源,进一步提升性能。