zoukankan      html  css  js  c++  java
  • 并发编程01

    并发编程——操作系统的发展史、多道技术、进程

    操作系统的发展史

    1.1 穿孔卡片

    • 读取数据速度特别慢
    • CPU的利用率极低
    • 单用户(一份代码)使用

    1.2 批处理

    • 读取数据速度特别慢
    • CPU利用率低
    • 联机(多份代码)使用

    1.3 脱机批处理(现代操作系统的设计原理)

    • 读取速度提高
    • CPU利用率提高

    多道技术(基于单核背景下产生的)

    单道:一条道走到黑(串行)

    比如: a,b需要使用cpu,a先使用,b等待a使用完毕后,b才能使用cpu。

    多道:一条路分配着走

    比如:a,b需要使用cpu,a先使用,b等待a,直到a进入“IO或执行时间过长”,a会(切换 + 保存状态),然后b可以使用cpu,待b执行遇到 “IO或执行时间过长”再将cpu执行权限交给a,直到两个程序结束

    空间上的复用

    多个程序使用一个CPU

    时间上的复用

    切换 + 保存状态

    ①:当执行程序遇到IO时,操作系统会将CPU的执行权限剥夺。

    ​ 优点:

    ​ CPU的执行效率高

    ②:当执行程序执行时间过长时,操作系统将cup的权限剥夺

    ​ 缺点:

    ​ 程序的执行效率低

    并发与并行

    并发:指资源有限的情况下,两者交替轮流使用资源,比如一段路同时只能过一人,A走完一段后,让给B,B走完继续给A,这样交替使用,目的是提高效率

    并行:指的是两者同时执行,比如赛跑,两个人一直都在不停地往前跑

    区别:

    ​ 并行是同时运行,只有具备多个CPU才能实现并行

    ​ 并发是伪并行,看起来像同时运行,单个CUP+多道技术可以实现并发(并行也属于并发)

    进程

    什么是进程?

    进程是一个资源单位,指正在进行的一个过程或者说一个任务

    进程与程序的区别

    程序仅仅只是一堆代码而已, 而进程指的是程序的运行过程。

    进程调度

    ①:先来先服务调度算法

    谁先来先服务谁,待服务完毕后,再服务下一个

    缺点:执行效率低

    ②:短作业优先调度算法

    谁执行的时间越短,优先调度谁

    缺点:导致执行时间长的程序,需要等待所有时间短的程序全部执行完毕后,才能执行

    ③:时间片轮转法

    让每个进程在就绪队列中的等待时间与享受服务的时间成比例。在时间片轮转法中,需要将CPU的处理时间分成固定大小的时间片,例如,几十毫秒至几百毫秒。如果一个进程在被调度选中之后用完了系统规定的时间片,但又未完成要求的任务,则它自行释放自己所占有的CPU而排到就绪队列的末尾,等待下一次调度。同时,进程调度程序又去调度当前就绪队列中的第一个进程。

    ④:多级反馈队列

    同步异步

    同步异步都指的是“提交任务的方式”

    同步(串行):

    一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列。要么成功都成功,失败都失败,两个任务的状态可以保持一致。

    异步(并发):

    不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了整个任务就算完成了。至于被依赖的任务最终是否真正完成,依赖它的任务无法确定,所以它是不可靠的任务序列。

    阻塞与非阻塞

    阻塞(等待):

    凡是遇到IO都会阻塞:

    ​ input()

    ​ time.sleep(3)

    ​ output()

    ​ ……

    非阻塞(不等待):

    除了IO都是非阻塞

    进程的三种状态

    • 就绪态
    • 运行态
    • 阻塞态

    进程的两种创建方式

    # 方式一:直接调用process
    from multiprocessing import Process
    import time
    
    
    def task():
        print("start...")
        time.sleep(3)
        print("end...")
    
    
    # 注意:要把创建子进程的部分放在  if __name__ == "__main__": 保护起来 否则在import时会造成无限递归
    if __name__ == "__main__":
        # target=任务 ---> 创建一个子进程
        p_obj = Process(target=task)
        # start() ---> 告诉操作系统,去创建一个子进程
        p_obj.start()
        # join() ---> 告诉主进程,等待子进程结束后,再结束
        p_obj.join()
        print("正在执行当前主进程...")
        
        
    # 方式二:继承 Process 类,并重写它的 run() 方法来创建进程类,程序创建 Process 子类的实例作为进程。
    class MyProcess(Process):
        def run(self):
            print(f"{self.name}的子进程start...")
            time.sleep(3)
            print(f"{self.name}的子进程end...")
    
    
    if __name__ == "__main__":
        list1 = []
        
        for line in range(10):
            obj = MyProcess()
            obj.start()
            list1.append(obj)
            
        for obj in list1:
            obj.join()
            
        print("主进程...")
    
  • 相关阅读:
    Docker Warning : the backing xfs filesystem is formatted without d_type support
    docker 版本变化及说明
    CORS 跨域请求
    nginx 用户登录认证
    PipelineDB On Kafka
    Postgres 主从配置(五)
    exec() has been disabled for security reasons
    invalid PID number "" in "/usr/local/nginx/logs/nginx.pid"
    未连接到互联网
    github管理代码
  • 原文地址:https://www.cnblogs.com/aheng/p/11997347.html
Copyright © 2011-2022 走看看