串行问题:并发
多道处理技术 (*******************)
1. 时间的复用,cpu在多个任务之间不断的进行切换异步
2. 空间的复用
多个任务必须开辟属于本身的内存空间 (物理级别的隔离)函数
相关概念:(*******************)
cpu: 计算执行任务的 不会执行IO操做(I/O输入/输出(Input/Output))
spa
cpu切换的条件:
1. 遇到IO操做,就切换
2. 遇到优先级比较高的任务会进行切换
3. 若是某一个任务长时间占用CPU资源,也会切换 , 要全部的任务雨露均沾操作系统
什么是串行、并发以及并行继承
a. 串行 : 程序一个接一个的执行
b. 并发 : 单个CPU执行多个程序任务, CPU在程序之间不断的进行切换, 感受好像是并行 (伪并行)
c. 并行 : 多个CPU同时执行多个程序任务进程
什么是进程
进程和程序的区别:
程序:静态的程序代码
进程:正在运行的程序ip
进程的开启方式(有两种方式)内存
开启进程须要调用multprocessing包下的Process资源
进程开启方式1,函数方式 (推荐这种方式,简单明了)
import time
from multiprocessing import Process #调用multprocessing包
def task(x):
print('%s is running' % x)
time.sleep(2)
print('%s is done' % x)
if __name__ == '__main__':
p = Process(target=task, args=('子进程',)) #开启进程须要实例化,开始进程实例
PS:实例化进程,须要执行的任务的目标函数就是task。当调用的时候就会将‘子进程’传给task函数的形参x
p.start() #向操做系统申请资源,开启子进程(包括子进程的空间大小,子进程的pid号,)
print('主...')
PS:Process里面的参数,traget就是执行任务的目标函数,args必须传入一个元祖(‘子进程’,),kwargs传一个字典{‘x’: '子进程'}就是传入的值(value)要赋值给哪个变量(key)
PS:执行程序的时候,是从上而下运行的,因此在程序执行到开启子进程的时候(p.start),就是在主进程里开启了一个子进程,p.start这里就是向操做系统申请了一块内存空间,而后执行子进程的程序,可是申请的时间是慢于主进程,由于程序是一直由上而下的运行,不会停顿,开启子进程须要申请内存空间,这个动做是要向操做系统去申请,而后操做系统开辟一个内存空间给子进程,这一个过程是很是耗费资源和时间的,因此主进程的速度是快于子进程
进程开启方式2 类方式
from multiprocessing import Process
import time
class MyProcess(Process): #本身写一个类,可是这个类必需要继承Process类的
def __init__(self,x = None): #
super(MyProcess,self).__init__() #由于是继承Prcess类,因此要在Process类的基础上增长咱们本身要的参数,要重写初始化函数
self.x = x #self.x是成员变量
def run(self): #子进程执行的这个函数不能乱写,必需要重写Process类下面的run
print('%s is running'%self.x)
print('%s is done' %self.x)
if __name__ == '__main__':
p = MyProcess('子进程') #这里实例化的是本身写的类
p.start()
print('主...')
子进程底层的运行原理
程序的运行的时候是由上而下运行,主进程是一个顺序的运行过程,在主进程运行的p.start()的时候,出现了一个分支运行了一个子进程,这时候主进程是不会中止的,继续向下运行,这时候子进程也是在运行,这个就叫作异步
主进程结束同时也会回收子进程
底层的运行原理
因为主进程(父进程)不知道子进程何时结束,因此主进程须要循环不断的向子进程发送一个wait/waitpd()函数,就是不断的向子进程询问状态(有没有执行完),收到子进程已经执行完的状态后,就会向操做系统发送请求,告诉操做系统全部的程序都已经执行完毕,这时候退出程序。
PS:全部的子进程在执行完毕以后并不会当即消失,操做系统会收回子进程占用的内存空间,可是会保留进程号,进程执行时间等,这个过程叫僵尸进程,全部的子进程都会经历一个过程叫僵尸进程,在僵尸进程时候就会告诉主进程已经执行完毕
进程的故障
一、主进程没结束,子进程还在运行,可是父进程不发送wait函数
主进程还在运行,主进程也不会向子进程循环发送一个wait/waitpd()函数,这时候主进程结束了,子进程继续在运行,若是操做系统里面主进程生成了大量的子进程,可是不回收,会致使系统奔溃死机,这时候用指令找到僵尸进程的父进程,直接杀死父进程,重启须要的进程便可
二、父进程结束,子进程继续运行(子进程就是孤儿进程)
孤儿进程会被一个权限最高的进程 init 进程接管,进程号(0),代替主进程的角色向子进程发送wait/waitpid()