Python多进程multiprocessing、进程池用法实例分析

1. multiprocessing模块介绍

Python中的multiprocessing模块是一个用于支持多进程编程的标准库,通过multiprocessing可以同时在多个CPU上运行Python代码,从而实现多进程编程,增强程序的并发处理能力,提升编程效率。multiprocessing实现了Unix/Linux下的fork()方法来创建进程,然而,由于Windows系统不支持fork()方法,所以multiprocessing在Windows系统下另外开发了一个Python模块,称为“代理模块”。

2. multiprocessing模块使用方法

2.1 创建进程

multiprocessing模块提供了多个类可用于创建进程,常用的有Process和Pool。Process类可以创建单个进程,Pool类可以创建一组进程,称为进程池。创建进程的方法与线程类似,首先需要创建一个进程对象,如下所示:

import multiprocessing

def worker():

print("This is worker")

p = multiprocessing.Process(target=worker)

p.start()

代码中的multiprocessing.Process类用于创建一个进程实例,其中target参数用于指定需要在进程中执行的函数,start()方法用于启动进程。

2.2 进程间通信

多个进程之间可以使用队列、管道等方式进行通信,multiprocessing模块中提供了Pipe、Queue等工具类,用于实现进程间通信。下例演示了两个进程之间通过管道进行通信的过程:

import multiprocessing

def worker(conn):

conn.send('worker to main')

print('from main:', conn.recv())

if __name__ == '__main__':

parent_conn, child_conn = multiprocessing.Pipe()

p = multiprocessing.Process(target=worker, args=(child_conn,))

p.start()

print('from worker:', parent_conn.recv())

parent_conn.send('main to worker')

p.join()

代码中两个进程之间通过Pipe类进行通信,先创建一个管道,调用Pipe方法得到管道的两个端点parent_conn和child_conn,父进程parent_conn对管道写,子进程child_conn对管道读,故其中一个进程先调用recv()方法来接收消息,另一个进程再调用send()方法来发送消息。

3. 进程池Pool的用法

常用的创建Pool的方式为multiprocessing.Pool,其中也可以传递参数processes来指定进程池的大小,默认是CPU核心数。对于CPU密集型任务,将进程数量设置为CPU核心数较为合理。下例演示了如何使用进程池创建多个进程来执行任务:

import multiprocessing

import time

def worker(num):

time.sleep(1)

print(num)

if __name__ == '__main__':

pool = multiprocessing.Pool()

for i in range(5):

pool.apply_async(worker, (i,))

pool.close()

pool.join()

上述代码中,首先通过multiprocessing.Pool()创建进程池对象,然后通过apply_async方法向进程池中添加任务,其中worker为任务函数,(i,)为任务函数的参数。

4. 进程池中map、imap、imap_unordered方法的用法

4.1 map方法

map()方法可以向进程池中传入多个参数,并自动均分参数到各个进程中,并返回各进程的执行结果,比较适用于小数据规模的处理。以下是一段使用map方法的示例:

import multiprocessing

import time

def worker(x):

return x ** 2

if __name__ == '__main__':

pool = multiprocessing.Pool()

results = pool.map(worker, [1, 2, 3, 4, 5])

print(results)

pool.close()

上述代码中,我们定义了一个worker()方法用来执行任务,然后使用Pool的map()方法来执行任务,传入的参数为[1,2,3,4,5]。执行任务之后,map()方法会自动将不同参数分配到不同的进程中,并将各进程的结果汇总起来。

4.2 imap方法

imap()方法是map()方法的改进,它可以实现异步处理,即不要等所有进程都做完,就可以立即获取结果。当进程池已满时,imap()方法会自动阻塞,直到有进程空闲出来。

import multiprocessing

import time

def multisq(n):

return n*n

if __name__ == '__main__':

pool = multiprocessing.Pool()

results = pool.imap(multisq, [1,2,3,4,5])

print(list(results))

pool.close()

上述代码中,我们定义了一个multisq()方法,用来执行任务,并传入参数[1,2,3,4,5]。我们通过Pool的imap()方法来执行任务,得到的结果是一个迭代器。需要使用list()函数转换为列表,才能得到结果。此外,imap_unordered()方法与imap()方法类似,不同之处是,结果的顺序与调用顺序不一定一致,取决于该进程最先完成任务的进程。

5. 实际应用

在实际应用中,多进程处理常用于计算密集型任务,其实就是指需要大量计算和处理的任务,包括数据的处理、模型的训练以及启动大量子进程等。在实际操作中,需要根据任务特性选择不同进程管理方案,比如使用Pool可以方便地实现进程池,不需要关注进程的创建和结束,便于调度。而对于需要更精细控制的场景,可以使用Process类来手动创建和结束进程。

6. 总结

本文介绍了Python中的multiprocessing模块的使用方法,包括如何创建进程、进程间通信、进程池等。为了提高多进程的处理效率,介绍了进程池中的map、imap、imap_unordered方法的使用。此外,本文还提到了多进程处理的实际应用场景,需要根据具体的任务特性来选择合适的进程管理方案。

免责声明:本文来自互联网,本站所有信息(包括但不限于文字、视频、音频、数据及图表),不保证该信息的准确性、真实性、完整性、有效性、及时性、原创性等,版权归属于原作者,如无意侵犯媒体或个人知识产权,请来电或致函告之,本站将在第一时间处理。猿码集站发布此文目的在于促进信息交流,此文观点与本站立场无关,不承担任何责任。

后端开发标签