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