Python自动化运维快速入门
上QQ阅读APP看书,第一时间看更新

3.1 创建进程的类Process

multiprocessing模块提供了一个创建进程的类Process,其创建进程有以下两种方法。


创建一个Process类的实例,并指定目标任务函数。

自定义一个类并继承Process类,重写其__init__()方法和run()方法。


我们首先使用第一种方法创建两个进程,并与单进程运行的时间做比较。


【示例3-1】定义耗时任务,并对比单进程和多进程耗时(multi_process.py)。

上面的代码首先定义了一个上亿次数据累加的耗时函数,在运行结束时打印调用此函数的进程ID,第14和15行是单进程执行,第18和19行分别实例化了Process类,并指定目标函数为task_process,第21和22行是双进程并行执行,执行完成后打印耗时。其运行结果如下:

父进程pid为 2116.
进程pid为 2116,执行完成
进程pid为 2116,执行完成
顺序执行耗时 37.13105368614197
进程pid为 60624,执行完成
进程pid为 41016,执行完成
多进程并发执行耗时 24.04837417602539

我们发现多进程执行相同的操作次数耗时更少。接下来我们使用第二种方法实现【示例3-1】。


【示例3-2】自定义一个类并继承Process类(multi_process2.py)。

提示

进程p0、p1在调用start()时,自动调用其run()方法。

运行结果如下:

父进程pid为 57228.
进程pid为 59932,执行完成
进程pid为 61288,执行完成
多进程并发执行耗时 24.03329348564148

下面我们来看一下Process类还有哪些功能可以使用,该类的构造函数原型如下。

class multiprocessing.Process(group=None, target=None, name=None, args=(),
kwargs={}, *, daemon=None)

参数说明如下。


target表示调用对象,一般为函数,也可以为类。

args表示调用对象的位置参数元组。

kwargs表示调用对象的字典。

name为进程的别名。

group参数不使用,可忽略。


类提供的常用方法如下。


is_alive():返回进程是否是激活的。

join([timeout]):阻塞进程,直到进程执行完成或超时或进程被终止。

run():代表进程执行的任务函数,可被重写。

start():激活进程。

terminate():终止进程。


属性如下。


authkey:字节码,进程的准密钥。

daemon:父进程终止后自动终止,且不能产生新进程,必须在start()之前设置。

exitcode:退出码,进程在运行时为None,如果为–N,就表示被信号N结束。

name:获取进程名称。

pid:进程id。


【示例3-3】不设置daemon属性(multi_process_no_daemo.py)。

这里没有使用p0.join()来阻塞进程。运行结果如下:

2018-07-11 21:13:30 父进程执行开始
2018-07-11 21:13:30 父进程执行结束
2018-07-11 21:13:30 子进程执行开始
sleep 3s
2018-07-11 21:13:33 子进程执行结束

可以看出,父进程并没有等待子进程运行完成就打印了退出信息,程序依然会等待子进程运行完成。


【示例3-4】设置daemon属性(multi_process_daemo.py)。

运行结果如下:

2018-07-11 21:17:33 父进程执行开始
2018-07-11 21:17:33 父进程执行结束

程序并没有等待子进程结束而结束,只要主程序运行结束,程序即退出。