• 1021 笔记


    操作系统发展史

    1.穿孔卡片

    手工操作,且一个计算机机房,只能被一个用户使用

    2.联机批处理系统

    支持多用户去使用一个计算机机房,主机与输入机之间增加一个存储设备——磁带,在运行于主机上的监督程序的自动控制下,计算机可自动完成

    3.脱机批处理系统

    为克服与缓解:高速主机与慢速外设的矛盾,提高CPU的利用率

    特征是:增加一台不与主机直接相连而专门用于与输入/输出设备打交道的卫星机。主机与卫星机可并行工作,二者分工明确,可以充分发挥主机的高速计算能力。

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

    为改善CPU的利用率,又引入了多道程序系统

    4.多道程序系统

    所谓多道程序设计技术,就是指允许多个程序同时进入内存并运行,并允许它们交替在CPU中运行,当一道程序因I/O请求而暂停运行时,CPU便立即转去运行另一道程序

    单道程序运行过程

    多个使用者使用CPU时是串行的

    img

    在A程序计算时,I/O空闲, A程序I/O操作时,CPU空闲(B程序也是同样);必须A工作完成后,B才能进入内存中开始工作,两者是串行的,全部完成共需时间=T1+T2。

    多道程序运行过程

    将A、B两道程序同时存放在内存中,它们在系统的控制下,可相互穿插、交替地在CPU上运行

    * 空间上的复用:	
    	多个程序公用一个内存,彼此隔离,物理级别的隔离
    * 时间上的复用:	
    	共用一个cpu
    	1.若CPU遇到IO操作,会立即将当前程序CPU使用权断开
    	​	优点:	CPU利用率高
    	2.若一个程序使用CPU的时间过长,会立即将房钱执行程序CPU使用权断开
    	​	缺点:	程序执行率降低
    

    多道程序系统的出现,标志着操作系统渐趋成熟的阶段,先后出现了作业调度管理、处理机管理、存储器管理外部设备管理、文件系统管理等功能。

    并发与并行

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

    ​ 并行: 真实意义上的同时运行,在多核的情况下,同时执行多个程序. 多核

    ​ 串行: 一个任务完整执行结束,再运行下一个任务

    进程

    进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础

    1.程序与进程

    程序: 一堆代码

    程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念
    

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

    进程是程序在处理机上的一次执行过程,它是一个动态的概念。
    

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

    5.调度状态

    进程执行时的间断性,决定了进程可能具有多种状态。

    就绪态

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

    运行态

    调度后的进程,进入进程态

    阻塞态

    凡是遇到I/O操作的进程,都会进入阻塞态,I/O结束后,必须重新进入就绪态

    6.进程回收

    1.进程回收的两种条件

    • join,可以回收子进程与主进程
    • 主进程正常结束,子进程与主进程也会被回收

    2.僵尸进程

    指的是子进程已经结束,但PID号还存在,未销毁

    缺点: 占用PID号,占用操作系统资源

    PID号:PID是各进程的代号,运行时系统随机分配,但是进程终止后PID标识符就会被系统回收,进程号具有固定数量.
    

    3.孤儿进程

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

    操作系统优化机制:自动回收此类子进程

    4.守护进程

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

    p.daemon = true 设置为守护进程

    p.daemon = true  (设置为守护进程)
    p.start
    # 必须在p.start之前设置,如果在之后会报错
    
    

    3.进程对象的属性

    1.current_process().pid

    在子进程内使用,可以获取子进程号

    from multiprocessing import Process
    from multiprocessing import current_process
    
    def task():
        print('开始执行...',current_process().pid)
        print('结束执行')
        
    if __name__ == '__main__':
        p = Process(target=task)  # 获得process对象
        p.start()  # 创建子进程
        p.join()    # 执行完子进程在执行主进程
        print('主进程')
    '''开始执行... 2092
    结束执行
    主进程'''
    

    2.os.getpid()

    在主进程中获得主进程号.

    from multiprocessing import Process
    from multiprocessing import current_process
    import os
    
    def task():
        print('开始执行...',current_process().pid)
        print('结束执行')
    
    if __name__ == '__main__':
        p = Process(target=task)  # 获得process对象
        p.start()  # 创建子进程
        p.join()    # 执行完子进程在执行主进程
        print('主进程',os.getpid())
    '''
    开始执行... 11072
    结束执行
    主进程 13892
    '''
    

    3.os.getppid

    可以查看主主进程的进程号(pycharm中运行代码,主主进程就是pycharm)

    def task():
        print('开始执行...',current_process().pid)
        time.sleep(1)
        print('结束执行')
    
    if __name__ == '__main__':
        p = Process(target=task)  # 获得process对象
        p.start()  # 创建子进程
        p.join()    # 执行完子进程在执行主进程
        print('主进程',os.getpid())
        print('主主进程',os.getppid())
        time.sleep(1000)
    '''
    开始执行... 12368
    结束执行
    主进程 10332   # python.exe
    主主进程 4152  # pycharm64.exe
    '''
    

    4.join()方法

    代码

    会让子进程结束后再结束主进程

    # 让子进程结束后,父进程才结束
    from multiprocessing import Process
    import time
    
    def task(name):
        print('任务开始')
        time.sleep(1)
        print('任务结束')
    
    if __name__ == '__main__':
        p = Process(target= task,args=('你好',))
        p.start() # 告诉操作系统,开启子进程
        print('join上面的不算')
        p.join()   # 告诉操作系统,等子进程结束后,父进程再结束
        print('主进程')
    '''
    join上面的不算
    任务开始
    任务结束
    主进程'''
    

    多个子程序的运行

    # 多个子进程的运行
    from multiprocessing import Process
    import time
    
    def task(name,n):
        print(f'{name}任务{n}开始')
        time.sleep(1)
        print(f'{name}任务{n}结束')
    
    if __name__ == '__main__':
        p1 = Process(target= task,args=('AAA',1))
        p2 = Process(target= task,args=('BBB',2))
    
        p1.start() # 告诉操作系统,开启子进程
        p2.start() # 告诉操作系统,开启子进程
        print('join上面的不算')
        p1.join()   # 告诉操作系统,等子进程结束后,父进程再结束
        p2.join()   # 告诉操作系统,等子进程结束后,父进程再结束
        print('主进程')
    '''
    join上面的不算
    AAA任务1开始
    BBB任务2开始
    AAA任务1结束
    BBB任务2结束
    主进程
    '''
    打印时会出现任务1,2顺序的不一致,貌似是因为程序并行导致cpu分配执行打印速度导致
    

    5.is_alive()

    判断子进程是否存活

    def task():
        print('开始执行...',current_process().pid)
    
    if __name__ == '__main__':
        p = Process(target=task)  # 获得process对象
        p.start()  # 创建子进程
        print(p.is_alive())   # 判断子进程是否存活
        print('主进程',os.getpid())
    '''
    True
    主进程 3740
    开始执行... 7004'''
    

    6..terminate()

    直接告诉操作系统,终止子程序

    def task():
        print('开始执行...',current_process().pid)
    
    if __name__ == '__main__':
        p = Process(target=task)  # 获得process对象
        p.start()  # 创建子进程
        # 判断子进程是否存活
        print(p.is_alive())
        # 告诉操作系统直接终止掉子进程
        p.terminate()
        time.sleep(0.1)
        # 判断子进程是否存活
        print(p.is_alive())
        print('主进程',os.getpid())
    '''
    True
    False
    主进程 7976'''
    

    7.tasklist | findstr+进程号

    # cmd 中查询进程号: tasklist | findstr 进程号
    

    4.进程的创建

    错误示范

    from multiprocessing import Process
    import time
    # 1.定义一个任务
    def task(name):
        print(f'{}的任务开始执行')
        time.sleep(1)
    
    # target = 执行函数的地址  args= 是传入函数的变量元组形式
    p = Process(target=task,args=('abc0',))
    # 向操作系统提交创建进程的任务
    p.start()
    '''注意: 在Windows下:创建子进程,会将当前父进程的代码重新加载执行一次
    以上执行创建子进程时会创建新的空间,会形成递归.
    linux/mac:  会将当前父进程代码重新拷贝一份,再去执行
    '''
    

    1.创建进程方式1

    from multiprocessing import Process
    import time
    # 1.定义一个任务
    def task(name):
        print(f'{name}的任务开始执行')
        time.sleep(1)
        print(f'{name}的任务结束执行')
    
    if __name__ == '__main__':
        # target = 执行函数的地址  args= 是传入函数的变量元组形式
        p = Process(target=task,args=('abc0',))
        # 向操作系统提交创建进程的任务
        p.start()
        print('主进程')
        '''# 先执行主进程,在创建的字进程执行
    主进程
    abc0的任务开始执行
    abc0的任务结束执行
    '''
    

    2.创建进程方式2

    自定义一个类,并继承Process

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

    5.进程之间的数据相互隔离

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

    from multiprocessing import Process
    
    x = 100
    
    def func():
        global x
        x = 20
    
    if __name__ == '__main__':
        p = Process(target= func)
        p.start()
        print(x)
        print('主程序')
        
    '''x = 100 '''
    
    

    并行/串行/并发

    1. 概念
    
    假设有AB两个任务,则串行、并行、并发的区别如图1所示。
    
    ###### 串行
    
    A和B两个任务运行在一个CPU线程上,在A任务执行完之前不可以执行B。即,在整个程序的运行过程中,仅存在一个运行上下文,即一个调用栈一个堆。程序会按顺序执行每个指令。
    
    ###### 并行
    
    并行性指两个或两个以上事件或活动在同一时刻发生。在多道程序环境下,并行性使多个程序同一时刻可在不同CPU上同时执行。比如,A和B两个任务可以同时运行在不同的CPU线程上,效率较高,但受限于CPU线程数,如果任务数量超过了CPU线程数,那么每个线程上的任务仍然是顺序执行的。
    
    ###### 并发
    
    并发指多个线程在宏观(相对于较长的时间区间而言)上表现为同时执行,而实际上是轮流穿插着执行,并发的实质是一个物理CPU在若干道程序之间多路复用,其目的是提高有限物理资源的运行效率。 并发与并行串行并不是互斥的概念,如果是在一个CPU线程上启用并发,那么自然就还是串行的,而如果在多个线程上启用并发,那么程序的执行就可以是既并发又并行的。
    

    同步和异步

    指的是提交任务的方式

    同步

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

    同步,是所有的操作都做完,才返回给用户结果

    异步

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

    异步,不用等所有操作等做完,就响应用户请求

    阻塞与非阻塞

    阻塞

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

    非阻塞

    就绪态,运行态

    面试题

    同步和异步,阻塞与非阻塞是同一个概念么

    答:不是同一个概念,不能混为一谈. IO操作与代码的执行

    最大化提高CPU的使用率提高,尽可能减少io操作

  • 相关阅读:
    git 提交解决冲突(转载)
    impala系列: 时间函数
    impala系列: 字符串函数
    Impala系列: Impala常用的功能函数
    impala系列:impala特有的操作符
    impala系列: 同步Hive元数据和收集统计信息
    ETL脚本的版本管理方法和 SourceTree 使用
    几本不错的数据仓库和Hadoop书籍
    Kudu系列-基础
    sql parser
  • 原文地址:https://www.cnblogs.com/fwzzz/p/11715736.html
Copyright © 2020-2023  润新知