一 、背景知识
顾名思义,进程即正在执行的一个过程。进程是对正在运行程序的一个抽象。
进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一。操作系统的其他所有内容都是围绕进程的概念展开的。所以想要真正了解进程,必须事先了解操作系统
操作系统发展史:参考博客即可:https://www.cnblogs.com/Dominic-Ji/articles/10929381.html
必备的理论基础:
#一 操作系统的作用: 1:隐藏丑陋复杂的硬件接口,提供良好的抽象接口 2:管理、调度进程,并且将多个进程对硬件的竞争变得有序 #二 多道技术: 1.产生背景:针对单核,实现并发 ps: 现在的主机一般是多核,那么每个核都会利用多道技术 有4个cpu,运行于cpu1的某个程序遇到io阻塞,会等到io结束再重新调度,会被调度到4个 cpu中的任意一个,具体由操作系统调度算法决定。 2.空间上的复用:如内存中同时有多道程序 3.时间上的复用:复用一个cpu的时间片 强调:遇到io切,占用cpu时间过长也切,核心在于切之前将进程的状态保存下来,这样 才能保证下次切换回来时,能基于上次切走的位置继续运行
二、多道技术
1 、单核实现并发的效果
-
并发
看起来像是同时运行的可以称之为并发
-
并行
真正意义上的同时执行
总结:
-
并行肯定是并发
-
单核的计算机不能实现并行,但是可以实现并发
补充:我们直接假设单核就是一个核,干活的就一个人,不要考虑cpu里面的内核数
2 、多道技术图解
3 、多道技术重点
- 空间上的复用
- 多个程序共用一套计算机硬件
- 时间上的复用
-
只需要做时间长的那个,可以节省切换时间
- 保存状态,用户态和内核态的切换 切换+保存状态
切换(CPU)分为两种情况 1.当一个程序遇到IO操作的时候,操作系统会剥夺该程序的CPU执行权限 作用:提高了CPU的利用率 并且也不影响程序的执行效率 原因:在io延迟的时候程序对cup没有任何执行的空间,所以剥夺了也不会影响程序运行 2.当一个程序长时间占用CPU的时候,操作吸引也会剥夺该程序的CPU执行权限 弊端:降低了程序的执行效率(原本时间+切换时间)
三、进程理论
1 、必备知识点
''' 程序和进程的区别 程序是一堆躺在硬盘上的代码,是‘死’的 进程则是表示正在执行的过程,是‘活’的 '''
2、 进程调度
- 先来先服务调度算法
- 对执行时间长的作业有利,对短作业无益。
- 因为一个长作业先到的话,后面一个短作业就得等长作业执行完毕才能把cup空间空给短作业
- 短作业优先算法
- 对短作业优先
- 如果一个长作业正在运行,来了一个短作业,这时候会先暂停长作业,把短作业运行完毕后回到长作业继续执行
- 时间片轮转法+多级反馈队列
- 不管长作业还是短作业都先放到一个队列中,统一执行一个规定的单位时间
- 如果没在规定时间执行完,会掉入第二优先级队列,再执行一个较长的单位时间
- 此时来了一个作业会直接暂停第二梯队去执行第一梯队的工作
- 总结:活用了切换和保存状态,优化了不同大小作业的执行效率
3 、进程的三状态
在了解其他概念之前,我们首先要了解进程的几个状态。在程序运行的过程中,由于被操作系统的调度算法控制,程序会进入几个状态:就绪,运行和阻塞。
(1)就绪(Ready)状态
当进程已分配到除CPU以外的所有必要的资源,只要获得处理机便可立即执行,这时的进程状态称为就绪状态。
(2)执行/运行(Running)
状态当进程已获得处理机,其程序正在处理机上执行,此时的进程状态称为执行状态。
(3)阻塞(Blocked)状态
正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引起进程阻塞的事件可有多种,例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等。
4 、两对重要概念
描述的是任务提交的方式
- 同步
- 解释:任务提交之后,在原地等待任务的返回结果,等待的过程中不去做任何事情,看上去像是程序卡住了
- 异步
- 解释:任务提交之后,不等待任务的返回结果,直接去做别的事情
- 任务的返回结果会有一个异步回调机制自动处理
就像要把一份作业交给老师批改,小红交给老师了,站在原地等老师批改完,小红的行为叫做同步。而小李交给老师后就跑去完了,这种行为叫做异步。
描述的是程序运行的状态
- 阻塞(阻塞态)
- 是我们程序运行基本都会遇到的状态,等待io操作
- 非阻塞(就绪态,运行态)
- 是我们程序运行的理想状态,只在就绪态和运行态之间切换,减少io延迟
四、开启进程的两种方式
# 方式一 from multiprocessing import Process import time def task(name): print(f'{name} is running') time.sleep(3) print(f'{name} is over') if __name__ == '__main__': p = Process(target=task, args=('hz',)) p.start() print('^(* ̄(oo) ̄)^') # 方式二 类的继承 from multiprocessing import Process import time class MyProcess(Process): def run(self): print('hell 1') time.sleep(3) print('hello 2') if __name__ == '__main__': p = MyProcess() p.start() print('^(* ̄(oo) ̄)^')
总结
""" 创建进程就是在内存中申请一块内存空间将需要运行的代码丢进去 一个进程对应在内存中就是一块独立的内存空间 多个进程对应在内存中就是多块独立的内存空间 进程与进程之间数据默认情况下是无法直接交互,如果想交互可以借助于第三方工具、模块 """
join方法
join是让主进程等待子进程代码运行结束之后,再继续运行。不影响其他子进程的执行
具体使用:在进程开始后,进程对象.join()
进程之间的数据相互隔离
from multiprocessing import Process import time a = 100 def task(name): print(f'{name} is running') time.sleep(3) global a a = 101 print(a) print(f'{name} is over') if __name__ == '__main__': p = Process(target=task, args=('hz',)) p.start() print(a) p.join() print('^(* ̄(oo) ̄)^')