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 父进程执行结束
程序并没有等待子进程结束而结束,只要主程序运行结束,程序即退出。