zoukankan      html  css  js  c++  java
  • 并发编程的一些理解

    进程:一个资源集合单位,是一个抽象的概念,进程指的是程序的执行过程
    线程:每一个进程都自带一个线程,线程是进程中代码的实际执行单位,可以把进程看做一个车
    间,里面有所有车间工作的必要资料、工具和流水线,那么流水线实际在这个车间里生产产品,相
    当于cpu在执行进程内的具体函数方法代码,由这个例子知道,线程之间可以共享车间的资源,而
    且线程的开启可以很快速,因为不需要向操作系统申请内存空间。

    阻塞:等待一个有效输入或者I/O完成,等待运算所需资源就位
    就绪:等待CPU权限,所有运算所需资源已经就位,CPU权限获取后立马可以运算
    运行:取得CPU权限,利用获取的资源正在运算

    多线程和多进程都是基于多道技术:
    多道技术:
      空间上的复用:实现程序在内存中的物理隔离
      时间上的复用:cpu时间片的轮转,遇到IO或者运行时间达到一定时间,交出CPU运行权限

    多进程:每个进程都是独立的存在,对进程内数据的修改仅限于该进程内
    优点:可以利用多核,实现并行运算,适用于cpu密集型程序
    缺点:进程开启开销大,切换开销大
    多线程:每个进程都只能同时有一个线程运行,因为GIL的存在,无法实现并行,但可以在IO密集型程序实现并发
    优点:创建线程的开销极小,切换速度快,相对于多进程在IO密集型更有优势,可以实现资源的共享
    缺点:一次只能运行一个线程,无法利用计算机的多核优势
    进程池:进程并不是越多越好,进程数目一旦多起来,系统就会有更多的时间浪费在进程的切换开
    销上,一旦切换开销的时间大于多进程执行节约的时间,那么多进程是没有必要的,于是限定并发
    的进程数,在进程池建立后,操作系统会立即建立相应数目的进程,进程开启请求发出后,所有进
    程请求都会由进程池其中随机的一个已经创建的进程响应执行,如果进程池满了,后续的进程无法响
    应,必须等到正在运行的进程结束,进程池有空闲进程可以复用,新的进程请求才可以开启。
    生产者和消费者模型:
      各自根据自己的能力生产和消费,通过阻塞队列来通信,平衡了生产者和消费者的处理能力

    GIL
      GIL是CPython解释器的全局锁,顾名思义,GIL是一把锁在解释器上的锁,每个进程启动,调
    用CPython解释器执行的时候都会在进程中生成一把GIL全局锁,一个进程中多线程并发的情况下,
    所有启动的线程去竞争GIL,拿到了GIL就相当于拿到CPython解释器的执行权限,可以调用解释器
    执行代码,因为一个进程只有一个CPyton解释器的GIL,所以在多核计算机中,即使给其他线程分
    配了CPU执行权限,但因为该线程没有得到解释器的执行权限即使有CPU可以用于运算,仍然无法执
    行线程代码。因此,必须等到拿到GIL的线程释放GIL。然后所有的线程再去竞争GIL,争夺CPython
    解释器的执行权限,循环反复,一个进程下始终只会有一个线程可以得到解释器的执行权限。

    也即是说:任何时刻,一个进程内都只有一个线程在运算,当然,因为CPU在各个线程将切换执行
    的速度非常快,所以我们可以看到几乎所有线程都在同时进行,达到多线程并发的效果
      当然和多进程中一样,操作系统会检查各个线程的活动状态,一旦线程进入I/O操作或者占用
    CPU的时间切片达到一定长度,会被操作系统强制解除CPU权限,这样因为该线程没有CPU资源可
    执行代码,CPython解释器会立即要求其交出GIL,将GIL释放,然后所有线程再次一起竞争GIL。

  • 相关阅读:
    vue中height设置为100%却无法铺满整个页面
    cpp快速上手
    CSP_2020061_线性分类器
    cpp快速上手
    算法笔记
    cpp中set的使用
    cpp中vector的使用
    常用命令
    常用git命令
    Linux使用docker安装fastfs
  • 原文地址:https://www.cnblogs.com/li1992/p/8963946.html
Copyright © 2011-2022 走看看