Python中的并发

Python中的并发

Python实现并发现在主要有三种方式:进程、线程和协程

本文先主要讲述进程和线程,由于之前写过有关进程和线程的文章,所以这里就不再贴代码,演示实现过程了,需要的同学请前往

下一篇文章将会讲解有关协程的姿势

Python的设计是任何一个进程在任何一个时刻只运行一个线程,不管你的系统内有多少CPU,程序控制是通过GIL实现的

首先明确两个概念:

CPU-bound:cpu处理大量数据,而像读取硬盘/内存这种是快速完成的

I/O-buund:大部分的状况是CPU在等待I/O(硬盘/内存)的读写

由于这种设定,Python的多线程在CPU-bound的情况下性能是非常差的,有些时候还会低于单线程。这是因为相比较于这种密集计算花费的时间,线程之间切换的时间会被放大。所以导致线程切换的时间在整个运算中占了大的比重。但是对于I/O-buund的情况,线程切换花费的时间在等待I/O花费的时间面前就不值一提,所以会提高很多的性能

Python中的并发

从上图中可以看到,某个线程要想运行就必须得抢到GIL,而GIL的释放都是由I/O触发的,如果有很多的I/O操作,多个线程就可以实现并发的执行,例如当网络爬虫的时候,就可以快速的切换GIL,从而实现多线程

而且其实GIL的设计使解释器变得更加容易实现了,可以不用考虑线程的安全性,在任何时刻只有一个线程能够获得Python对象或者嵌入的C/C++ API。

多进程处理实际上对每个任务都会生成一个操作系统的进程,并且每一个进程都被单独赋予了Python的解释器和GIL,所以你的程序在实际运行中有多个GIL存在,每个运行者的线程都会拿到一个GIL,在不同的环境下向前进,自然也可以被分配到不同的处理器上。这一点对于CPU-bound的任务程序非常有帮助。

这一解决方案提高了计算能力,但与此同时也引入了其他的一些问题。因为Python解释器是跟着进程走的,所以新的进程就引入了新的解释器,工作消耗的内存也成倍增长。这点对于那些需要存放很大的全局字典的互联网应用,是致命伤。

简单概括就是线程适合I/O-bound的应用,进程适合CPU-bound的应用,但是大部分情况下面对高效率,高并发的需求,Python可能不是最好的语言。

这里有本人写的适合新手的小项目,有意戳-->

欢迎大家关注头条号:热衷python和前端

如果有需要源码的同学就留言或者私聊我吧


分享到:


相關文章: