操作系统发展史
穿孔卡片
一个计算机机房,一次只能被一个卡片使用
缺点:
CPU利用率最低
联机批处理系统
支持多用户去使用一个计算机机房
脱机批处理系统
高速磁盘:
提高文件得读取速度
优点:
提高CPU得利用率
多道技术(基于单核请况下研究)
-单道:多个使用使用CPU时是串行
-多道:
-空间上的复用:
一个CPU可以提供给多个用户使用
-时间上的复用:
切换+保存状态
IO操作:
input()
print()
time.sleep()
1)若CPU遇到IO操作,会立即讲当前执行程序CPU使用权断开
优点:CPU的利用率高
2)若一个程序使用CPU的时间过长,会立即将当前执行程序CPU使用权断开
缺点:程序的执行率降低
并发与并行
并发:指的是看起来像同时在运行,多个程序不停得 切换+保存状态
并行:真实意义上的同时运行,在多核的情况下,同时执行多个程序
进程
程序与进程
-程序:一堆代码
-进程:一堆代码运行的过程
进程调度
当代操作系统调度:
时间片轮转法+分级反馈队列
1)先来先服务调度:
a,b程序,若a程序先来,先占用CPU
缺点:程序a先使用,程序b必须等待程序a使用CPU结束后才能使用。
2)短作业优先调度:
a,b程序,谁的用时短,先优先调度使用CPU
缺点:若程序a使用时间最短,有N个程序使用时间短,必须等待所有用时短的程序结束后才能使用。
3)时间片轮转法:
CPU执行的时间1秒中,加载N个程序,要将1秒等分成多N个时间片。
4)分级反馈队列
将执行优先分多层级别。
-1级:优先级最高
-2级:优先级第二,依次类推
-3级:
进程的三个状态:
-就绪态:
所有进程创建时都会进入就绪态,准备调度
-运行态:
调度后的进程,进入运行态
-阻塞态:
凡是遇到IO操作的进程,都会进入阻塞态。若IO结束,必须重新进入就绪态。
创建进程的两种方式
#第一种
#windows:创建子进程,windows会将当前父进程代码重新加载执行依次
#Linux/mac:会将当前父进程代码重新拷贝一份,再去执行(在Linux/mac系统下不会报错)
from multiprocessing import Process
import time
#定义一个任务
def task(name):
print(f'{name}的任务开始执行')
time.sleep(1)
print(f'{name}的任务已经结束')
if __name__ == '__main__':
p=Process(target=task,args=('nick',))
p.start()
print('主进程')
time.sleep(3)
'''
主进程
nick的任务开始执行
nick的任务已经结束'''
#第二种
# 自定义一个类,并继承Process
class MyProcess(Process):
def run(self):
print('任务开始执行')
time.sleep(1)
print('任务已经结束')
if __name__ == '__main__':
p=MyProcess()
p.start()
print('主进程')
time.sleep(3)
'''主进程
任务开始执行
任务已经结束
hello
'''
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=('nick',))
p.start()#告诉操作系统,开启子进程
p.join()#告诉操作系统,等子进程结束后,父进程再结束
print('主进程')
'''
nick start...
nick over
主进程'''
进程间数据是相互隔离的
'''
进程间数据下过户隔离:
主进程与子进程会产生各自的名称空间
'''
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('主进程')
'''100
主进程
执行func函数'''
进程对象的属性
'''
current_process().pid:获取子进程号
os.getpid():获取主进程pid号
os.getppid():获取主主进程pid号
cmd种查找进程号:tasklist |findstr 进程号
p.is_alive():判断子进程是否存活
p.terminate():直接告诉操作系统,终止子进程,随后必须加上time.sleep(0.1)
'''
from multiprocessing import Process
from multiprocessing import current_process
import os
import time
def task(name):
print(f'{name} start....',current_process().pid)
time.sleep(3)
print(f'{name} over...',current_process().pid)
if __name__ == '__main__':
p=Process(target=task,args=('nick',))
p.start()#告诉操作系统,开启子进程
print(p.is_alive())#判断子进程是否存活
p.terminate()
time.sleep(0.1)
print(p.is_alive())
p.join()#告诉操作系统,等子进程结束后,父进程再结束
print('主进程',os.getpid())
print('主主进程',os.getppid())
'''True
True
主进程 6788
主主进程 9120'''
同步和异步
指的是提交任务的方式
-同步:
若有两个任务需要提交,在提交第一个任务时,必须等待该任务执行结束后,才能继续提交并执行第二个任务
-异步:
若有两个任务需要提交,在提交第一个任务时,不需要原地等待,立即可以提交并执行第二个任务
阻塞与非阻塞
-阻塞:
阻塞态,遇到IO一定会阻塞
-非阻塞:
就绪态
运行态
面试题:同步和异步,阻塞和非阻塞式同一个概念吗
强调:不是同一个概念,不能混为一谈!
最大化提高CPU的使用率:
尽可能减少不必要的IO操作
进程号回收的两种条件:
1.join,可以回收子进程与主进程。
2.主进程正常结束,子进程与主进程也会被回收
僵尸进程与孤儿进程(了解)
僵尸进程:
指的是子进程已经结束,但是PID号还存在,未销毁
缺点:占用PID号,占用操作系统资源
孤儿进程:
指的是子进程还在执行,但是父进程意外结束。
操作系统优化机制;提供一个福利院,帮你回收没有父进程的子进程
守护进程:
指的是主进程结束后,该主进程产生的所有子进程跟着结束,并回收
from multiprocessing import Process
from multiprocessing import current_process
import time
def task(name):
print(f'{name} strat...',current_process().pid)
time.sleep(2)
print(f'{name} over...',current_process().pid)
if __name__ == '__main__':
p=Process(target=task,args=('nick',))
p.daemon=True# True代表该进程是守护进程
p.start()
print('主进程结束')
'''主进程结束'''