(day28)操作系统发展史+进程

目录

  • 一、操作系统发展史
    • (一)穿孔卡片(手工操作)
    • (二)批处理系统(磁带存储)
      • 1. 联机批处理系统
      • 2. 脱机批处理系统
    • (三)多道技术
  • 二、进程
    • (一)程序和进程
    • (二)进程调度
      • 1. 先来先服务调度
      • 2. 短作业优先调度
      • 3. 时间片轮转法
      • 4. 分级反馈队列
    • (三)程序调度时的三个状态
      • 就绪态
      • 运行态
      • 阻塞态
    • (三)同步和异步
    • (四)阻塞与非阻塞
    • (五)创建进程的两种方式
    • (六)join方法
    • (七)进程间数据是相互隔离的
    • (八)进程对象的属性
    • (九)僵尸进程与孤儿进程(了解)
    • (十) 守护进程
  • 面试题

一、操作系统发展史

(一)穿孔卡片(手工操作)

  • 一个计算机机房只能被一个卡片使用

    缺点:CPU利用最低

(二)批处理系统(磁带存储)

1. 联机批处理系统

  • 支持多用户去使用一个计算机机房

2. 脱机批处理系统

  • 高速磁盘:提高文件的读取速度
  • 优点:提高CPU的利用率

(三)多道技术

  • 单道:多个使用CPU时是串行

  • 多道(基于单核情况下):

    1. 空间上的复用

      一个CPU可以提供给多个用户使用

    2. 时间上的复用(读取记忆保存)

      切换+保存状态

      • 若CPU遇到IO操作,会立即将当前执行程序CPU使用权断开

        优点:CPU的利用率高

      • 若一个程序使用CPU的时间过长,也会立马将当前执行程序使用权断开

        缺点:程序的执行降低

    3. 并发和并行

      并发:看起来像同时在运行,多个程序不停切换+保存状态

      并行:真正意义上的同时在运行,在多核(多个CPU)情况下,同时执行多个程序

二、进程

(一)程序和进程

  • 程序:一堆代码
  • 进程:一堆代码运行的过程

(二)进程调度

1. 先来先服务调度

根据先后顺序

2. 短作业优先调度

根据用时长短

3. 时间片轮转法

cpu执行的时间1s中,加载N个程序,将1秒等分成多个时间片

4. 分级反馈队列

将执行优先分为多层级别

(三)程序调度时的三个状态

就绪态

所有进程创建时都会进入就绪态,准备调度

运行态

调度后的进程进入运行态

阻塞态

凡是遇到IO操作的进程都会进入阻塞态

若IO结束,必须重新进入就绪态

(三)同步和异步

指的时提交任务的方式

  • 同步

    若有两个任务需要提交,在提交任务时,必须等待该任务执行结束后才能继续提交并执行第二个任务

  • 异步

    若有两个任务提交,在提交第一个任务时,不需要原地等待,立即可以提交并执行第二个任务

(四)阻塞与非阻塞

  • 阻塞

    阻塞态,遇到IO一定会阻塞

  • 非阻塞

    就绪态和运行态

(五)创建进程的两种方式

  1. 创建进程方式一
from multiprocessing import Process
import time
# 定义一个任务
def task(name):
    print(f'{name}开始执行任务')
    time.sleep(1)
    print(f'{name}的任务已经结束')
    
# target = 执行函数的地址,json位元组,传值给target指向的函数    
if __name__ == '__main__':
    p = Process(target = task,args = ('json',))

    # 像操作系统提交创建进程
    p.start()
  • windows

    在window系统下,创建子进程,windows会把父进程代码重新加载一次

  • linux/max

    会将当前父进程代码重新拷贝一份,再去执行

  1. 创建方式2
class MyProcess(Process):
    def run(self):  # 必须是run
        print(f'{name}开始执行任务')
        time.sleep(1)
        print(f'{name}的任务已经结束')

if if __name__ == '__main__':
    p = MyProcess()
    p.start()     

(六)join方法

告诉操作系统,让子进程结束后再结束父进程

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 = ('json',))
    p.start()  # 告诉操作系统启动子进程
    p.join()  # 告诉操作系统先结束子进程,再结束父进程
    print('主进程')

(七)进程间数据是相互隔离的

主进程和子进程回有各自的名称空间

from multiprocess import Process

x = 100

def func():
    global x
    x = 200
    
if __name__ == '__main__':
    p = Process(target = func)
    p.start()
    print(x)  # 100
    print('主进程')

(八)进程对象的属性

  • current_process().pid:获取子进程号

    os.getpid():获取主进程号

    os.getppid():获取主主进程号

    p.is_alive():判断子进程是否存活

    p.terminate():终止子进程

  • cmd中查看进程号:tasklist|findstr 进程号

  • 进程号回收的两种条件

    1. join,可以回收子进程与主进程
    2. 主进程正常结束,子进程与主进程也会被回收
from multiprocessing import Process
from multiprocessing import current_process
import os
import time

def task(name):
    # 获取子进程号
    print(f'{name}开始执行任务',current_process().pid)
    time.sleep(1)
    print(f'{name}的任务已经结束',current_process().pid)

if __name__ == '__main__':
    p = Process(target = task,args = ('json',))
    p.start() 
    p.join()  
    # 直接告诉操作系统,终止子进程
    p.terminate()
    time.sleep(0.1)  # 主进程进入阻塞态,子进程进入运行态
    
    # 判断子进程是否存活
    print(p.is_alive())
    
    # 获取主进程号
    print('主进程',os.getpid())  
    
    # 获取主主进程号
    print('主主进程',os.getppid())

(九)僵尸进程与孤儿进程(了解)

  • 僵尸进程

    指的是,子进程已经结束,但是pid号还存在,没有销毁,会占用pid号,占用操作系统资源

  • 孤儿进程

    指的是,子进程还在执行,但父进程意外结束

    操作系统优化机制:会回收孤儿进程

(十) 守护进程

指的是,主进程结束后,该主进程产生的所有子进程也会跟着结束,并结束

p1.daemon = True :代表是守护进程

面试题

  1. 同步和异步,阻塞和非阻塞是同一个概念吗?

    答:不是同一个概念,不能混为一谈

  2. 最大化提高cpu的使用率:

    尽可能减少不需要的IO操作

你可能感兴趣的:((day28)操作系统发展史+进程)