并发编程的一些理解

进程:一个资源集合单位,是一个抽象的概念,进程指的是程序的执行过程
线程:每一个进程都自带一个线程,线程是进程中代码的实际执行单位,可以把进程看做一个车
间,里面有所有车间工作的必要资料、工具和流水线,那么流水线实际在这个车间里生产产品,相
当于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。

 

posted @ 2018-04-27 18:46  Leslie-x  阅读(168)  评论(0编辑  收藏  举报