操作系统发展史
1)穿孔卡片
一个计算机机房,一次只能被一个卡片使用
缺点: CPU利用率最低
2)联机批处理系统
支持多用户去使用一个计算机机房
3)脱机批处理系统
高速磁盘: 提高文件的读取速度
优点: 提高CPU的利用率
- 多道技术
-
单道
多个使用CPU时是串行
必须让一个程序结束后,下一个程序才能继续执行
-
多道技术
-
空间上的复用:
一个CPU可以提供给多个用户去使用
-
时间上的复用:
切换 + 保存
IO操作:
input()
print()
time.sleep()
1)若CPU遇到IO操作,会立即将当前执行程序CPU使用权断开
优点: CPU的利用率高
2)若一个程序使用CPU的时间过程,也会立即将该执行程序的CPU使用权断开
-
-
并发与并行
并发:指的是看起来像同时在运行,多个程序不停 切换 + 保存状态
并行: 真实意义上的同时运行,在多核(多个CPU)的情况下,同时执行多个程序
进程
-
程序与进程
-
程序: 一堆代码
-
进程: 一堆代码运行的过程
-
-
进程调度
-
先来先调度
a,b程序, 若a程序先来,先占用CPU
缺点: 程序a先使用,程序b必须等程序a使用CPU结束后才能使用
-
短作业优先调度
a,b程序,谁用时短,先优先调度使用CPU
缺点: 若程序a使用时间最长,有N个程序使用时间短,必须等待所有用时短的程序结束后才能使用
-
时间片轮转法
CPU执行的时间1秒中,加载N个程序,要将1秒等分成多个N个时间片
-
分级反馈队列
将执行优先分为多层级别
-
1级: 优先级别最高
-
2级: 优先等级第二,以此类推
-
.........
-
-
进程的三个状态
-
就绪态
所有进程创建时都会进入就绪态,准备调度 -
运行态
调度后的进程,进入运行态 -
阻塞态
凡是遇到IO操作的进程,都会进入阻塞态
若IO结束,必须重新进入就绪态
-
-
-
同步和异步:
指的是提交任务的方式
-
同步
若有两个任务需要提交,在提交第一个任务时,
必须等待该任务执行结束后,才能继续提交执行第二个任务
import time def test(): # IO操作 # time.sleep(3) # 计算操作 num = 1 for line in range(1000000000000000000000000): num += 1 if __name__ == '__main__': test() print('hello tank')
-
异步
若有两个任务需要提交,在提交第一个任务时,
不需要原地等待,立即可以提交并执行第二个任务
-
-
阻塞与非阻塞
-
阻塞:
阻塞态,遇到IO一定会阻塞
-
非阻塞
就绪态
运行态
面试题: 同步和异步,阻塞和非阻塞是同一个概念吗?
强调: 不是同一个概念,不能混为一个谈!
-
最大化提高CPU的使用率:
尽可能减少不必要的IO操作
创建进程的两种条件
-
join,可以回收子进程与主进程
''' join方法: 用来告诉操作系统,让子进程结束后,父进程再结束。 ''' # from multiprocessing import Process # import time # # # def task(name): # print(f'{name} start...') # time.sleep(2) # print(f'{name} over..') # # # if __name__ == '__main__': # p = Process(target=task, args=('jason', )) # p.start() # 告诉操作系统,开启子进程 # p.join() # 告诉操作系统,等子进程结束后,父进程再结束。 # print('主进程') from multiprocessing import Process import time def task(name, n): print(f'{name} start...') time.sleep(n) print(f'{name} over..') if __name__ == '__main__': p1 = Process(target=task, args=('jason', 1)) p2 = Process(target=task, args=('egon', 2)) p3 = Process(target=task, args=('sean', 3)) p1.start() p2.start() # 告诉操作系统,开启子进程 p3.start() # 告诉操作系统,开启子进程 p1.join() # 告诉操作系统,等子进程结束后,父进程再结束。 p2.join() p3.join() print('主进程')
-
主进程正常结束,子进程与主进程也会被回收
''' 进程间数据相互隔离: 主进程与子进程会产生各自的名称空间。 ''' from multiprocessing import Process x = 100 def func(): print('执行func函数...') global x x = 200 if __name__ == '__main__': p = Process(target=func) p.start() print(x) print('主')
僵尸进程与孤儿进程(了解)
僵尸进程: 指的是子进程已经结束,但PID号还存在,未销毁
缺点: 占用PID号,占用操作系统资源
孤儿进程:指的是子进程还在执行,但父进程意外结束
操作系统优化机制: 提供一个福利院,帮你回收没有父亲的子进程
守护进程
指的是主进程结束后,该进程产生的所有的进程跟着结束,并回收
注意: 必须在start() 之前设置
from multiprocessing import Process
from multiprocessing import current_process
import time
def task(name):
print(f'{name} start...', current_process().pid)
time.sleep(5)
print(f'{name} over..', current_process().pid)
print(f'管家{name}')
if __name__ == '__main__':
p1 = Process(target=task, args=('jason', ))
# 添加守护进程参数
p1.daemon = True # True代表该进程是守护进程
p1.start()
print(f'egon 驾鹤西去...')