并发编程01
并发编程——操作系统的发展史、多道技术、进程
操作系统的发展史
1.1 穿孔卡片
- 读取数据速度特别慢
- CPU的利用率极低
- 单用户(一份代码)使用
1.2 批处理
- 读取数据速度特别慢
- CPU利用率低
- 联机(多份代码)使用
1.3 脱机批处理(现代操作系统的设计原理)
- 读取速度提高
- CPU利用率提高
多道技术(基于单核背景下产生的)
单道:一条道走到黑(串行)
比如: a,b需要使用cpu,a先使用,b等待a使用完毕后,b才能使用cpu。
多道:一条路分配着走
比如:a,b需要使用cpu,a先使用,b等待a,直到a进入“IO或执行时间过长”,a会(切换 + 保存状态),然后b可以使用cpu,待b执行遇到 “IO或执行时间过长”再将cpu执行权限交给a,直到两个程序结束
空间上的复用
多个程序使用一个CPU
时间上的复用
切换 + 保存状态
①:当执行程序遇到IO时,操作系统会将CPU的执行权限剥夺。
优点:
CPU的执行效率高
②:当执行程序执行时间过长时,操作系统将cup的权限剥夺
缺点:
程序的执行效率低
并发与并行
并发:指资源有限的情况下,两者交替轮流使用资源,比如一段路同时只能过一人,A走完一段后,让给B,B走完继续给A,这样交替使用,目的是提高效率
并行:指的是两者同时执行,比如赛跑,两个人一直都在不停地往前跑
区别:
并行是同时运行,只有具备多个CPU才能实现并行
并发是伪并行,看起来像同时运行,单个CUP+多道技术可以实现并发(并行也属于并发)
进程
什么是进程?
进程是一个资源单位,指正在进行的一个过程或者说一个任务
进程与程序的区别
程序仅仅只是一堆代码而已, 而进程指的是程序的运行过程。
进程调度
①:先来先服务调度算法
谁先来先服务谁,待服务完毕后,再服务下一个
缺点:执行效率低
②:短作业优先调度算法
谁执行的时间越短,优先调度谁
缺点:导致执行时间长的程序,需要等待所有时间短的程序全部执行完毕后,才能执行
③:时间片轮转法
让每个进程在就绪队列中的等待时间与享受服务的时间成比例。在时间片轮转法中,需要将CPU的处理时间分成固定大小的时间片,例如,几十毫秒至几百毫秒。如果一个进程在被调度选中之后用完了系统规定的时间片,但又未完成要求的任务,则它自行释放自己所占有的CPU而排到就绪队列的末尾,等待下一次调度。同时,进程调度程序又去调度当前就绪队列中的第一个进程。
④:多级反馈队列
同步异步
同步异步都指的是“提交任务的方式”
同步(串行):
一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列。要么成功都成功,失败都失败,两个任务的状态可以保持一致。
异步(并发):
不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了整个任务就算完成了。至于被依赖的任务最终是否真正完成,依赖它的任务无法确定,所以它是不可靠的任务序列。
阻塞与非阻塞
阻塞(等待):
凡是遇到IO都会阻塞:
input()
time.sleep(3)
output()
……
非阻塞(不等待):
除了IO都是非阻塞
进程的三种状态
- 就绪态
- 运行态
- 阻塞态
进程的两种创建方式
# 方式一:直接调用process
from multiprocessing import Process
import time
def task():
print("start...")
time.sleep(3)
print("end...")
# 注意:要把创建子进程的部分放在 if __name__ == "__main__": 保护起来 否则在import时会造成无限递归
if __name__ == "__main__":
# target=任务 ---> 创建一个子进程
p_obj = Process(target=task)
# start() ---> 告诉操作系统,去创建一个子进程
p_obj.start()
# join() ---> 告诉主进程,等待子进程结束后,再结束
p_obj.join()
print("正在执行当前主进程...")
# 方式二:继承 Process 类,并重写它的 run() 方法来创建进程类,程序创建 Process 子类的实例作为进程。
class MyProcess(Process):
def run(self):
print(f"{self.name}的子进程start...")
time.sleep(3)
print(f"{self.name}的子进程end...")
if __name__ == "__main__":
list1 = []
for line in range(10):
obj = MyProcess()
obj.start()
list1.append(obj)
for obj in list1:
obj.join()
print("主进程...")