• 进程


    1.操作系统发展史

      1)穿孔卡片: 一个计算机机房,一次只能被一个卡片使用。

        缺点:

         CPU利用率最低。

      2)联机批处理系统
        支持多用户去使用一个计算机机房。

      缺点:

        在作业输入和结果输出时,主机的高速CPU仍处于空闲状态

      3) 脱机批处理系统
        高速磁盘:
          提高文件的读取速度。
        优点:
          提高CPU的利用率  

                     

         

        卫星机:一台不与主机直接相连而专门用于与输入/输出设备打交道的。

        其功能是:

      1. 从输入机上读取用户作业并放到输入磁带上。
      2. 从输出磁带上读取执行结果并传给输出机。

      4)多道技术(基于单核情况下研究):

      

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

      - 多道技术:计算机内存中同时存放几道相互独立的程序
      - 空间上的复用(*******):
        一个CPU可以提供给多个用户去使用。

      - 时间上的复用(*******):
        切换 + 保存状态

      IO操作:
      input()
      print()
      time.sleep(3)

        1) 若CPU遇到IO操作,会立即将当前执行程序CPU使用权断开。
        优点:
        CPU的利用率高。

        2) 若一个程序使用CPU的时间过长,会立即将当前执行程序CPU使用权断开。
        缺点:
        程序的执行率降低。

      - 并发与并行:
      并发: 指的是看起来像同时在运行,多个程序不停 切换 + 保存状态。
      并行: 真实意义上的同时运行,在多核(多个CPU)的情况下,同时执行多个程序。

    2.进程

    - 程序与进程
    - 程序: 一堆代码。
    - 进程: 一堆代码运行的过程。

    - 进程调度:
    当代操作系统调度:
    时间片轮转法 + 分级反馈队列

    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级
    ....

    创建进程方式一:

    # 1.定义一个任务
    import timefrom multiprocessing import Process def task(name): print(f'{name}的任务开始执行') time.sleep(1) print(f'{name}的任务已经结束') # 在linux/mac系统下不会报错 # p = Process(target=task, args=('jason',)) if __name__ == '__main__': # target=执行函数的地址 p = Process(target=task, args=('jason',)) # 向操作系统提交创建进程的任务 p.start() print('主进程')

    运行结果:

      主进程
      jason的任务开始执行
      jason的任务已经结束

    创建进程的方式二:

    #创建进程方式二:
    #1.自定义一个类,并继承Process
    import timefrom multiprocessing import Process
    class MyProcess(Process): # 父类的方法 def run(self): print('任务开始执行') time.sleep(1) print('任务已经结束') if __name__ == '__main__': p = MyProcess() p.start() # p.start() print('主进程')
    运行结果:
    主进程 任务开始执行 任务已经结束

    join方法:

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

      

    from multiprocessing import Process
    import time
    
    
    def task(name):
        print(f'{name} start...')0
        time.sleep(2)
        print(f'{name} over..')
    
    
    if __name__ == '__main__':
        p = Process(target=task, args=('jason', ))
        p.start()  # 告诉操作系统,开启子进程
        p.join()  # 告诉操作系统,等子进程结束后,父进程再结束。
        print('主进程')
    打印结果:
    jason start... jason over.. 主进程
    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('主进程')
    打印结果:
    sean start... jason start... egon start... jason over.. egon over.. sean over.. 主进程

    进程间数据是相互隔离的

      主进程与子进程会产生各自的名称空间

      

    from multiprocessing import Process
    
    x = 100
    
    
    def func():
        print('执行func函数...')
        global x
        x = 200
        print(1111)
    
    
    
    if __name__ == '__main__':
        p = Process(target=func)
        p.start()
        p.join()
        print(x)
        print('')
    运行结果:
    执行func函数... 1111 100 主

    进程对象的属性

      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..', os.getpid())
    
    
    if __name__ == '__main__':
        p = Process(target=task, args=('jason', ))
        p.start()  # 告诉操作系统,开启子进程
       print(p.pid)
        # 判断子进程是否存活
        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)

    打印结果:
    True False 主进程 9688 主主进程 10680

    守护进程

    主进程结束,子进程也一起结束

    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代表该进程是守护进程  要在start()之前设置
        p1.start()
    
        print(f'egon ...')

    打印结果:
    egon ...

    - 进程的三个状态:

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

    - 运行态:
    调度后的进程,进入运行态。

    - 阻塞态:
    凡是遇到IO操作的进程,都会进入阻塞态。
    若IO结束,必须重新进入就绪态。

    - 同步和异步:
    指的是提交任务的方式。

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

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

    - 阻塞与非阻塞:
    - 阻塞:
    阻塞态。遇到IO一定会阻塞。

    - 非阻塞:
    就绪态
    运行态

    面试题: 同步和异步,阻塞和非阻塞是同一个概念吗?
    强调: 不是同一个概念,不能混为一谈!

    最大化提高CPU的使用率:
    尽可能减少不必要的IO操作。

    进程号回收的两种条件:
      1.join,可以回收子进程与主进程。
      2.主进程正常结束,子进程与主进程也会被回收。

    3.僵尸进程与孤儿进程(了解):

    僵尸进程:
    指的是子进程已经结束,但PID号还存在,未销毁.
    缺点:
    占用PID号,占用操作系统资源.

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

    4.守护进程:

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

  • 相关阅读:
    Spring中的资源加载
    分布式系统Paxos算法
    MySQL中MyISAM与InnoDB区别及选择(转)
    Unable to construct api.Node object for kubelet: can't get ip address of node master.example.com: lookup master.example.com on : no such host
    分库情况下的数据库连接注入
    Core源码(二) Linq的Distinct扩展
    B-Tree详解
    C#进阶之路(八)集合的应用
    重温CLR(十八) 运行时序列化
    重温CLR(十七)程序集加载和反射
  • 原文地址:https://www.cnblogs.com/fjn839199790/p/11714255.html
Copyright © 2020-2023  润新知