zoukankan      html  css  js  c++  java
  • Python学习之并发基础知识

    8 并发编程

    8.1 基础知识

    8.1.1 操作系统的定义

    操作系统是存在于硬件与软件之间,管理、协调、调度软件与硬件的交互。

    资源管理解决物理资源数量不足和合理分配资源这两个问题,

    通俗来说,操作系统可以分成两部分功能:

    ​ 一是将硬件资源接口的调用变得方便简单;
    ​ 二是合理调度应用程序对硬件资源的竞态请求

    8.1.2 进程

    具有独立功能的程序在某个数据集合上的一次运行活动,也是操作系统进行资源分配和保护的基本单位。

    正在执行的文件或程序,而负责执行的主体使CPU。

    8.1.3 进程与程序

    ​ 程序可以说是一些文件或者代码等指令的集合,程序不能单独执行,只有把程序加载到内存中,系统为它分配资源之后才能执行,而程序的执行就叫线程,进程包括程序、数据集和进程控制三个模块,是操作系统进行资源分配和保护的基本单位。

    ​ 把一个程序在一个数据集上的依次执行称为一个进程。程序是静态的指令集合,而进程是动态的。

    ​ 同一个程序同时执行两次也是两个进程。

    8.1.4 并行与并发

    并发:

    ​ 一个处理器同时处理多个任务;由CPU的多道技术实现,是逻辑上的同时发生,微观上仍是同一时刻只能执行一个任务,只不过CPU利用多道技术在多个任务键来回切换执行,而切换执行的时间差,我们无法察觉,宏观上感觉是多个任务同时发生。

    并行:

    ​ 指在同一时刻,有多条指令在多个处理器上同时执行,物理上真正实现多任务同时执行。

    多道技术:对单个CPU而言,空间上复用,内存中同时存入多道程序;时间复用,cpu在多个进程间快速切换(一是遇到io,二是执行一定的时间),使每个进程各自运行一定的时间。

    【重要概念】

    ​ 串行:所有的进程由CPU一个一个的执行
    ​ 并发:单个cpu同时执行多个进程(来回切换),看起来像是同时运行
    ​ 并行:多个cpu真正的同时运行多个程序
    ​ 阻塞:遇到IO(write input read sleep recv accept)才叫阻塞
    ​ 非阻塞:没有IO

    8.1.5 同步/异步&阻塞/非阻塞(重要)

    线程

    进程是负责程序执行的执行单元,一个进程中至少有一个线程。

    线程与进程的区别:

    • 进程是资源分配和调度的独立单元,线程是CPU调度的基本单位
    • 同一个进程中可能有多个线程,这些线程共享进程的资源,每个线程并行执行不同的任务
    同步

    发出一个功能调用时,在没有得到结果之前,该调用就不返回

    【常规用法】

    • multiprocessing.Pool下的apply 发起同步调用命令后,一直等到任务结束
    • concurrent.futures.ProcessPoolExecutor().submit(func,).result()
    • concurrent.futures.ThreadPoolExecutor().submit(func,).result()
    异步

    与同步概念相对,当异步功能调用后,调用者没有立即得到结果,而是等到异步功能完成后,通过状态、通知或者回调函数来通知调用者

    【常规用法】

    • multiprocessing.Pool().apply_async() 发起异步调用,并不会等待任务结束,只是得到一个对象,该对象是可变的,最终变成执行结果
    • concurrent.futures.ProcessPoolExecutor(3).submit(func,)
    • concurrent.futures.ThreadPoolExecutor(3).submit(func,)
    from concurrent.futures import ProcessPoolExecutor
    import os,time,random
    
    def f():
        print(f"{os.getpid()} is runing")
        time.sleep(random.randint(1,3))
        return f"{os.getpid()} is done "
    
    if __name__ == '__main__':
        p = ProcessPoolExecutor(max_workers=4)
        l = []
        sta1 = time.time()
        for i in range(10):
            obj = p.submit(f)   #  异步调用执行submit
            l.append(obj)
        print(f'take {time.time()-sta1} times')  # 时间非常短
    
        time.sleep(4)
        sta2 = time.time()
        for j in l:
            print(j.result())   # 每一个result都是同步调用
        print(f'take {time.time() - sta2} times')  # 总耗时时间比较长
    
    阻塞

    阻塞调用是指调用结果返回之前,当前线程会被挂起,如遇到IO操作,调用函数只有在得到结果之后才会将阻塞的线程激活

    非阻塞

    与阻塞的概念相对,指在不能立即得到结果之前也会立刻返回,同时该函数不会阻塞当前线程,程序没有遇到IO或者遇到IO后通过协程让CPU去执行本线程里的其他任务,尽可能占用CPU

    总结

    ​ 同步和异步关注的是消息通信机制,说的是任务的发布与结果的回收;
    ​ 阻塞和非阻塞关注的是进程在等待调用结果时的状态,阻塞是当请求不能满足的时候就将进程挂起,而非阻塞则不会阻塞当前进程

    仅供参考,欢迎指正
  • 相关阅读:
    大话设计模式之备忘录模式
    大话设计模式之模板方法模式
    大话设计模式之桥接模式
    大话设计模式之组合模式
    大话设计模式之适配器模式
    大话设计模式之原型模式
    大话设计模式之解释器模式
    大话设计模式之享元模式
    大话设计模式之迭代器模式
    dom操作排他思想
  • 原文地址:https://www.cnblogs.com/jjzz1234/p/11233388.html
Copyright © 2011-2022 走看看