day 28小结

操作系统发展史

1)穿孔卡片

​ 一个计算机机房,一次只能被一个卡片使用
​ 缺点: CPU利用率最低

2)联机批处理系统

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

3)脱机批处理系统

​ 高速磁盘: 提高文件的读取速度

​ 优点: 提高CPU的利用率

4) 多道技术

  • 单道

    多个使用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操作

创建进程的两种条件

  1. 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('主进程')
    
  2. 主进程正常结束,子进程与主进程也会被回收

    '''
    进程间数据相互隔离:
        主进程与子进程会产生各自的名称空间。
    
    '''
    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号,占用操作系统资源

​ 孤儿进程:指的是子进程还在执行,但父进程意外结束
​ 操作系统优化机制: 提供一个福利院,帮你回收没有父亲的子进程

守护进程

指的是主进程结束后,该进程产生的所有的进程跟着结束,并回收

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 驾鹤西去...')

猜你喜欢

转载自www.cnblogs.com/LZF-190903/p/11715399.html