并发编程基础及进程基础
并发编程基础及进程基础
1、操作系统发展史
1、穿孔卡片
读取速度很慢
CPU利用率很低
单个用户(一份代码)使用
2、批处理
读取速度慢
CPU利用率低
联机(多份代码)使用
效率低
3、脱机批处理(现代操作系统的设计原理)
读取速度提高
CPU利用率提高
2、多道技术(基于单核背景下产生)
单道:一条道走到黑(串行)
程序 a和b 都要使用CPU,a先使用CPU时,需要等待a使用结束后,b才开始使用CPU
多道:比如, a和b 都要使用CPU,a先使用CPU时,直到a遇到IO或者执行时间过长时,a会(切换+保存状态),然后b可以使用CPU,直到b遇到IO或者执行时间过长,b会(切换+保存状态),a再次执行,直到两个程序结束
IO: input() , output() , time.sleep(), 文件的读写,数据的传输
空间上的复用:多个程序使用一个CPU
时间上的复用:切换+保存状态
-
当执行程序遇到 IO 时,操作系统会将CPU的执行权限剥夺
优点:CPU的执行效率高
-
当执行程序时间过长时,操作系统会将CPU的执行权限剥夺
缺点:程序的执行效率低
并发与并行
并发:
在单核(一个CPU)的情况下,当执行当 a ,b 两个程序,先运行a时,当a遇到IO时,b开始执行,看着像同时运行
并行:
在多核情况下,当执行 a ,b 两个程序,a 与 b 同时执行,真正意义上的同时执行
3、进程
1、什么是进程
进程是一个资源单位
2、进程与程序的区别
程序:一堆代码文件
进程:执行代码的过程,称之为进程
3、进程调度
-
先来先服务调度算法
a , b 程序,当a 先来a就先执行,一直执行完后b才执行
缺点:执行效率低
-
短作业优先调度算法
执行时间短的先执行
缺点:导致执行时间长的程序,需要等待所有时间短的程序执行完毕后,才能执行
-
时间片轮转法
比如同时有10个程序 ,操作系统给1秒时间,每个程序分0.1秒运行,未运行完的进入下一次调度
-
多级反馈队列
1级队列:优先级最高,先执行
2级队列:优先级次之,1级队列执行完后执行
3级队列:。。。。
现在的操作系统的进程调度算法:时间片轮转法+多级反馈队列
4、同步与异步
同步与异指的是 提交任务的方式
同步(串行):程序 a和b 都要提交使用CPU,a先提交使用CPU时,需要等待a使用结束后,b才提交开始使用CPU
异步(并发):两个a,b程序都要提交并执行,假如a先提交并执行,b无需等a执行完毕,就可以直接提交任务
5、阻塞与非阻塞
阻塞(等待):凡是遇到IO都会阻塞
非阻塞(不等待):除了IO都是非阻塞
6、进程的三种状态
就绪态:同步与异步已经获取除CPU以外的所有资源,只要获取处理机就能立马执行的状态
运行态(非阻塞):已经获得处理机,正在执行的状态,程序的执行时间过长——>将程序返回给就绪态
阻塞态:遇到IO,处于阻塞状态
同步与异步指的是:提交任务的方式
阻塞与非阻塞:指的是进程的状态
异步非阻塞:CPU的利用率最大化
7、创建进程的两种方式
强调:在Windows操作系统中由于没有 fork ( linux 操作系统中创建进程的机制),在创建子进程的时候会自动 import 启动它的这个文件,而在 import 的时候又执行了整个文件。因此如果将process()直接写在文件中就会无限递归创建子进程报错。所以必须把创建子进程的部分使用if __ name__ ==‘ __ main__’ : 判断保护起来,import 的时候 ,就不会递归运行了。
from multiprocessing import Process
import time
# 方式1:直接调用Process
def test_data(name):
print(f'start{name}子进程')
time.sleep(2)
print(f'end{name}子进程')
if __name__ == '__main__':
# target = 函数地址,args = 函数传入的参数(元组)
obj = Process(target=test_data, args=('Jason',))
# 创建子进程
obj.start()
# 等着子进程结束完成后再结束
obj.join()
print('主进程')
from multiprocessing import Process
import time
# 方式2:使用类继承Process
class MyProcess(Process):
def run(self):
print(f'start子进程')
time.sleep(2)
print(f'end子进程')
if __name__ == '__main__':
list2 = []
for i in range(5):
obj = MyProcess()
obj.start()
list2.append(obj)
for obj in list2:
obj.join()
print('主进程结束')