系统自带的fork模块建立的多进程是基于Linux或Unix平台的,而window平台并不支持;html
python中的multiprocess为跨平台版本的多进程模块,支持子进程、通讯和共享数据、执行不一样形式的同步,提供了Process(进程)、Pool(进程池)、Queue(队列)、Pipe(管道)、Lock等组件python
建立进程的类:linux
Process([group [, target [, name [, args [, kwargs]]]]]) 编程
group:实质上不使用,线程组,目前尚未实现,库引用中提示必须是Nonewindows
target:调用对象/目标函数dom
name:给进程赋予一个名字函数
args:调用对象的位置参数元组 / 按位置给目标函数传参spa
kwargs:调用对象的字典 / 以字典形式向目标函数传参.net
实例方法 :线程
p为进程对象的属性
p.start() 启动某一个进程
p.join([timeout]) 主进程阻塞等待子进程timeout时间后的退出,在时间内若主进程已执行完成,暂时不会退出,而是等待子进程的退出,而后处理子进程后本身再退出
p.is_alive() 进程的状态
p.run() 调用run方法,若是实例进程时未制定传入target,这star执行t默认run()方法。
p.terminate() 无论任务是否完成,当即中止工做进程。
属性:
p.name 建立的进程的名称
p.authkey
p.exitcode(进程在运行时为None、若是为–N,表示被信号N结束)。
p.pid 建立的子进程PID号
p.daemon 若设置必须置于start调用前进行(和线程的setDeamon功能同样(将父进程设置为守护进程,当父进程结束时,子进程也结束);
默认为false,即主进程执行结束后不退出,等待子进程执行后先退出,而后主进程再退出;
设置为True时,主进程执行后当即退出,而且该主进程的全部子进程也退出
通常步骤为
(1)肯定事件,将事件封装为函数
(2)调用Process类生成响应的子进程对象
(3)调用start()运行子进程
import multiprocessing as mp def test(): pass p = mp.Process(target=test) # 建立子进程 p.start() # 开始执行子进程 p.join() # 等待子进程结束
注意:
一、Process对象能够建立进程,但Process对象自己不是进程。
二、主进程执行完毕后会默认等待子进程结束后回收资源,不须要手动回收资源;join()函数来控制父子进程的结束顺序,待子进程结束后清理子进程全部信息并回收资源。
三、采用Process对象建立进程后,子进程会将主进程的Process对象彻底复制一份,这样父子进程各有一个Process对象,p.start()启动子进程,主进程中的Process对象做为静态对象存在,不执行。
四、当子进程执行完毕后,产生的“僵尸进程”会被join()函数回收;或者再有另外一条进程开启,start()函数也会回收“僵尸进程”,因此不必定须要写join函数。
五、window系统平台中的子进程结束后会当即自动清除子进程的Process对象,而linux系统平台中的子进程Process对象结束后,若是没有join()函数或start()函数时则会在主进程结束后统一清除。
另外还能够经过继承Process对象来重写run方法建立进程,这里再也不赘述。
import multiprocessing as mp from time import sleep from random import randint import os def test(): sleep(randint(0,4)) print(os.getppid(),'-------',os.getpid()) print("Testing") for i in range(5): p = mp.Process(target=test) #原test()函数已经不是普通的函数,Process对象已经将其转变成进程。 p.start()
运行
4710 ------- 4711 Testing 4710 ------- 4715 Testing 4710 ------- 4712 Testing 4710 ------- 4713 Testing 4710 ------- 4714 Testing
说明:从运行结果可知,PID=4710的父进程建立了5个子进程(不一样的PID对应不一样的子进程)。
import multiprocessing as mp from time import sleep a = 10 def worker(sec): print(a) sleep(sec) print('worker ......') print(a) p = mp .Process(name = 'child', target = worker,args = (5,)) #元组传参 #p进程对象的属性 # p.daemon = True p.start() #启动进程 print(p.pid) #建立的子进程的PID号 print(p.name) #建立的进程的名称 print(p.is_alive()) #进程的状态 a = 100000 p.join() #主进程阻塞等待子进程的退出 print("************main****************") worker(1)
运行
5399 child True 10 worker ...... 10 ************main**************** 100000 worker ...... 100000
注意:
(1)元组传参args = (5,) 而非args = (5) ,一个元素时需注意。
(2)当建立子进程后,在主进程中从新绑定变量值时,子进程中的变量不会变化。
(3)p.daemon = True / False,
daemon(守护进程)默认是False,即主进程(阻塞)会等待子进程结束;
True则为直接结束主进程,子进程也随之结束,当主进程中加入阻塞函数join时,该句失效。
import multiprocessing as mp from time import sleep import os a = 100 def worker(sec,msg): print(a) sleep(sec) print(os.getppid(),'-------',os.getpid()) print(msg) print(a) for i in range(5): p = mp.Process\ (name = 'Child%d'%i,target=worker, # args = (2,"child process"),\ kwargs={'sec':2,'msg':"child process"}) p.start() sleep(1) a = 100000 p.join()
运行
100 100 100 100 100 5590 ------- 5592 child process 100 5590 ------- 5591 child process 100 5590 ------- 5593 child process 100 5590 ------- 5594 child process 100 5590 ------- 5595 child process 100
说明:
(1)这里面中的字典传参与元组传参的能够相互替代,但元素传参需注意位置关系
(2)开始时输出连续打印出100是因为子进程中sleep()所致,当去掉时,连续执行数次(>3)时100均非连续;同时子进程PID号也是乱序(此也说明子进程相互独立)。
from multiprocessing import Process #导入Process模块 import os def test(name): ''' :param : :return: 下段代码适用于Linux中运行,因windows下os模块不支持getppid() ''' print("Process ID: %s" % (os.getpid())) print("Parent Process ID: %s" % (os.getppid())) # windows下,建立进程的代码一下要放在main函数里面 if __name__ == "__main__": proc = Process(target=test, args=('nmask',)) proc.start() proc.join()
该段代码没有在window下尝试运行,在Linux虚拟机上运行正常;相信但要有所怀疑!
详细参看
multiprocessing解析(一):Process的解析