进程的概念
在Python程序中,想要实现多任务可以使用进程来完成,进程是实现多任务的一种方式
一个正在运行的程序或者软件就是一个进程,进程也是操作系统进行资源分配的最基本单位,也就是说每次启动一个软件(进程)操作系统都会给其分配一定的运行资源(内存资源)保证其正常工作运行
一个程序运行至少有一个进程,一个进程默认有一个线程,进程里面可以创建多个线程,线程是依附在进程里面的,没有进程就没有线程
程序运行起来,就会给其创建一个主进程,等待子进程结束后,再结束
比如:生活中的工厂(计算机),每一个车间是一个进程,工厂提供资源(占地面积、电力设备等),真正能够干活的是车间员工,员工可以理解为线程
单进程
默认程序运行创建一个进程
一个Python文件运行,就是开启一个进程去处理
进程中的场景:主线程去执行代码
多进程
一个Python文件运行,占用一个进程去处理,假如同时要运行第二个Python文件,同样给第二个Python文件开启一个进程去处理
多进程可以完成多任务,每个进程就好比一个独立车间,每个车间都各自在运营,每个进程也是各自在运行,执行各自的任务
多进程的使用
导入进程包
import multiprocessing
Process进程类的说明
Process([group,target,name,args,kwargs])进程类的构造
1. group:指定进程组,目前只能使用None
2. target:执行的目标任务名称
3. name:进程的名字
4. args:以元祖方式给执行的任务传递参数
5. kwargs:以字典方式给执行的任务传递参数
Process创建的实例对象常用的方法
1. start():启动子进程实例(启动创建子进程)
2. join():等待子进程执行结束,相当于给这个进程做了一个单独检测的功能,当这个子进程执行完毕之后主进程才继续往后执行
3. terminate():不管任务是否完成,立即终止子进程
Process创建的实例对象常用的属性
name:当前进程的别名,默认为Process-N,N为从1开始的递增整数
Process中kill的方法
进程编号
进程的编号的目的是验证主进程和子进程的关系,可以得知子进程是由哪个主进程创建出来的
获取进程编号的方式
- 获取当前进程的编号
使用os.getpid()获取当前进程的编号 - 获取当前父进程的编号
使用os.getppid()获取当前父进程的编号
所有的子进程都来自于父进程,因此一个程序中的主进程编号得知,子进程编号按照主进程编号为起始值加一计算
multiprocessing.current_process()方法获取当前的当前进程的详细信息(进程名称和进程编号)
进程的特性
进程之间不共享全局变量
当一个进程对全局变量进行数据的修改,对于其他进程而言不会造成任何的影响,可以理解为每个进程都拿的是最初始的全局变量。或者可以理解为全局变量就是所谓资源,当创建一个进程,则系统会直接给这个进程里面复制一个全局变量。针对于这个全局变量而言,在进程之间都是相互独立存在的,之间没有任何的联系
所有子进程结束主进程才会结束
主进程会等待所有的子进程执行结束之后才能结束
在主进程结束之前,手动结束了所有的子进程,那么程序的结束由主进程的结束来控制
如果需要实现主进程结束则整个程序结束:
- 在主进程结束之前,保证所有子进程结束使用子进程的terminate()
- 在子进程开启之前,设置当前子进程被被主进程守护,子进程的deamon属性设为true则意味着这个子进程被主进程守护,主进程结束守护结束,子进程也结束
单进程与多线程的优劣
1.单进程开发简单;多线程开发复杂
2.单进程在处理高并发时一般采用多启动进程的方式;多线程仅需启动多个线程。进程的切换开销比线程大
3.多进程之间如果有信息通信则相对多线程效率较低,因为多线程属于同一地址空间的访问,效率相对较高(暂不涉及锁等一致性策略的影响)
4.多进程稳定好,一个进程死了不影响其他进程;多线程中,任意一个出现问题,将影响到所有。