1.导入进程模块 import multiprocessing1.2 Process进程类的语法结构如下:Process([group [, target [, name [, args [, kwargs]]]]])group:指定进程组,目前只能使用Nonetarget:执行的目标任务名name:...
1.导入进程模块
import multiprocessing
1.2 Process进程类的语法结构如下:
Process([group [, target [, name [, args [, kwargs]]]]])
- group:指定进程组,目前只能使用None
- target:执行的目标任务名
- name:进程名字
- args:以元组方式给执行任务传参
- kwargs:以字典方式给执行任务传参
Process创建的实例对象的常用方法:
- start():启动子进程实例(创建子进程)
- join([timeout]):是否等待子进程执行结束,或等待多少秒
- terminate():不管任务是否完成,立即终止子进程
Process创建的实例对象的常用属性:
- name:当前进程的别名,默认为Process-N,N为从1开始递增的整数
- pid:当前进程的pid(进程号)multiprocessing.current_process().pid 或os.getpid()
- 获取父进程编号:os.getppid()
2.进程注意点
- 进程之间不共享全局变量(创建子进程其实是对主进程进行拷贝,进程进程之间相互独立,访问的全局变量不是同一个)需要使用Queue
- 主进程默认会等待所有的子进程执行完成后程序才会退出
- 可以为设置守护主进程 ,但是只能通过sub_process.daemon = True
- 可以直接销毁子进程,主进程退出之前把子进程销毁,sub_process.terminate()
3.进程间通信
queue添加数据:
queue = multiprocessing.Queue(maxsize=-1) # -1表示添加任意多个数据
queue.put(数据) # queue可以放入任何类型的数据 ,如果队列满了,数据会进行等待,直到消息队列有空闲位置才放入数据
queue.put_nowait(数据)# 队列如果满了,此方法会报错
queue判断队列是否满了
result = queue.full() # 若满了返回True
result = queue.empty() # 坑点,此方法判断消息队列不靠谱 ,不推荐使用
queue.qusize() # 查看当前队列里消息的个数
queue获取数据
value = queue.get() # 队列中的元素是FIFO(先进先出)
value = queue.get_nowait() # 若队列为空立即报错,不推荐使用
利用消息队列完成进程通信
进程池
用来自动创建大量线程,process_pool = multiprocessing.Pool(max_size)
初始化进程池时,可以指定一个最大进程数,当有新的请求提交到Pool时,如果池内有空闲进程则使用该进程,若无空闲进程,且进程池还未达到最大值,那么久会创建一个新的进程来执行该请求,若达到最大值,那么该进程就会等待,直到池中有进程结束,才会使用之前的进程来执行新的任务。
进程池分为同步执行任务和异步执行任务。
同步执行任务:process_pool.apply(work),默认创建的子进程为守护主进程的,但主进程会被阻塞到子进程执行结束
异步执行任务:process_pool.apply_async(work),创建的子进程是守护主进程的,但它是非阻塞的。
主进程需要等待进程池把所有任务完成才能退出
pool.close() # 关闭进程池,明确告诉主进程不再接受其它任务
pool.join() # 等待进程池完成所有任务
demo 进程池完成多任务版文件夹拷贝
进程池在执行任务的时候会尽量少创建进程,合理利用现有进程完成多任务,这样可以减少资源开销。