本人用的是window系统,所以就基于Windows系统来讲解python多进程的问题。
参考资料:廖雪峰的官方网站
由于Windows不同于Linux系统,所以在使用多进程时需要导入multiprocessing模块,模块提供了一个Process类来代表一个进程对象:
from multiprocessing import Process
import os
def Solution(name):
print("Run child process {0} {1}".format(name, os.getpid()))
if __name__ == "__main__":
print('Parent process {0}'.format(os.getpid()))
p = Process(target=Solution, args=('test',))
print("child process will start:")
p.start()
p.join()
print('child process end')
结果执行如下:
Parent process 7304
child process will start:
Run child process test 9668
child process end
代码分析:
1. 首先我们导入需要用到的multiprocessing模块跟os模块,然后创建一个用于测试的函数 Solution(),这个函数的作用只是打印一句话,来提示我们子进程已经正常工作了,子进程的 name 是通过主函数调用时传入的,os.getpid() 函数用于获取进程 ID,这个ID是系统在进程开辟的时候赋予的。
2. 主程序里面:首先打印 主进程的 ID,这个ID是区别于子进程ID的;然后利用 Process()方法创建子进程,
Process([group [, target [, name [, args [, kwargs]]]]])
这是Process方法的定义:
- group 分组,基本不会使用
- target 表示需要调用的函数方法,在这里我们调用函数Solution
- args 表示需要传给调用对象即Solution的参数,需要以元组的形式传入,在这里我们只传入一个 ‘test’ 参数,由于是元组形式,所以需要为(‘test',)否则解释器会把参数当成一个括号里面的元素
3 . 创建完子进程之后,我们先打印一句话,来提示子进程即将开始运行。
- p.start()方法表示子进程开始运行
- p.join()方法表示子进程结束之后,主进程才继续执行主函数之后的代码,如果不去调用 join()方法,极有可能会造成僵尸程序,即主程序已经结束了,但是子程序还在继续运行,继续消耗电脑资源
这是创建一个单子进程的方法,假如说我们需要创建多个子进程怎么办?这时候我们就可以使用进程池来批量创建子进程
from multiprocessing import Pool
import os
import time
import random
def Solution(name):
print('运行子进程 {0},进程ID:{1}'.format(name,os.getpid()))
start = time.time()
time.sleep(random.random() * 2)
end = time.time()
print('子进程{0}运行时间:{1}'.format(name,(end-start)))
if __name__ == "__main__":
print("主进程ID:{0}".format(os.getpid()))
p = Pool(processes=4)
for i in range(5):
p.apply_async(Solution, args= (i,))
print("请稍等:")
p.close()
p.join()
print("所有进程已结束!")
- 首先我们导入需要用到的库,multiprocessing用于创建多进程, os 用于获取进程的ID号,time 模块用于计算各个子进程的运行时间,random模块用于随机产生一个数字,然后让子进程进入休眠,即子进程的主要任务:睡觉
- 构造一个函数Solution():在里面首先打印子进程的名字以及ID号、start记录进程开始的时间、然后子进程进入休眠,时间随机。end记录进程结束的时间。最后打印子进程运行时间及name
- 主程序:首先打印主进程Id号。利用进程池 Pool 创建四个进程0、1、2、3、5 。利用for 循环调用子进程,相当于单步进行上面的单子进程。打印 “请稍等:” 。调用 close()方法,来关闭进程池,关闭之后就不能继续添加新的子进程了。调用join()方法。打印结果
下面是执行结果
主进程ID:6416
请稍等:
运行子进程 0,进程ID:13388
运行子进程 1,进程ID:6208
运行子进程 2,进程ID:6340
运行子进程 3,进程ID:10352
子进程3运行时间:0.05106353759765625
运行子进程 4,进程ID:10352
子进程2运行时间:0.08306264877319336
子进程0运行时间:0.13808250427246094
子进程4运行时间:0.39206528663635254
子进程1运行时间:1.932739496231079
所有进程已结束!
我们观察一下结果,进程0、1、2、3是立即执行,但是进程4是在某个进程运行结束之后才开始进行的,只是因为我的 Pool的大小默认为4