进程 vs. 线程(python的协程)(转廖雪峰老师python教程)

咱们介绍了多进程和多线程,这是实现多任务最经常使用的两种方式。如今,咱们来讨论一下这两种方式的优缺点。编程

首先,要实现多任务,一般咱们会设计Master-Worker模式,Master负责分配任务,Worker负责执行任务,所以,多任务环境下,一般是一个Master,多个Worker。服务器

若是用多进程实现Master-Worker,主进程就是Master,其余进程就是Worker。网络

若是用多线程实现Master-Worker,主线程就是Master,其余线程就是Worker。多线程

多进程模式最大的优势就是稳定性高,由于一个子进程崩溃了,不会影响主进程和其余子进程。(固然主进程挂了全部进程就全挂了,可是Master进程只负责分配任务,挂掉的几率低)著名的Apache最先就是采用多进程模式。并发

多进程模式的缺点是建立进程的代价大,在Unix/Linux系统下,用fork调用还行,在Windows下建立进程开销巨大。另外,操做系统能同时运行的进程数也是有限的,在内存和CPU的限制下,若是有几千个进程同时运行,操做系统连调度都会成问题。异步

多线程模式一般比多进程快一点,可是也快不到哪去,并且,多线程模式致命的缺点就是任何一个线程挂掉均可能直接形成整个进程崩溃,由于全部线程共享进程的内存。在Windows上,若是一个线程执行的代码出了问题,你常常能够看到这样的提示:“该程序执行了非法操做,即将关闭”,其实每每是某个线程出了问题,可是操做系统会强制结束整个进程。异步编程

在Windows下,多线程的效率比多进程要高,因此微软的IIS服务器默认采用多线程模式。因为多线程存在稳定性的问题,IIS的稳定性就不如Apache。为了缓解这个问题,IIS和Apache如今又有多进程+多线程的混合模式,真是把问题越搞越复杂。spa

线程切换

不管是多进程仍是多线程,只要数量一多,效率确定上不去,为何呢?操作系统

咱们打个比方,假设你不幸正在准备中考,天天晚上须要作语文、数学、英语、物理、化学这5科的做业,每项做业耗时1小时。线程

若是你先花1小时作语文做业,作完了,再花1小时作数学做业,这样,依次所有作完,一共花5小时,这种方式称为单任务模型,或者批处理任务模型。

假设你打算切换到多任务模型,能够先作1分钟语文,再切换到数学做业,作1分钟,再切换到英语,以此类推,只要切换速度足够快,这种方式就和单核CPU执行多任务是同样的了,以幼儿园小朋友的眼光来看,你就正在同时写5科做业。

可是,切换做业是有代价的,好比从语文切到数学,要先收拾桌子上的语文书本、钢笔(这叫保存现场),而后,打开数学课本、找出圆规直尺(这叫准备新环境),才能开始作数学做业。操做系统在切换进程或者线程时也是同样的,它须要先保存当前执行的现场环境(CPU寄存器状态、内存页等),而后,把新任务的执行环境准备好(恢复上次的寄存器状态,切换内存页等),才能开始执行。这个切换过程虽然很快,可是也须要耗费时间。若是有几千个任务同时进行,操做系统可能就主要忙着切换任务,根本没有多少时间去执行任务了,这种状况最多见的就是硬盘狂响,点窗口无反应,系统处于假死状态。

因此,多任务一旦多到一个限度,就会消耗掉系统全部的资源,结果效率急剧降低,全部任务都作很差。

计算密集型 vs. IO密集型

是否采用多任务的第二个考虑是任务的类型。咱们能够把任务分为计算密集型和IO密集型。

计算密集型任务的特色是要进行大量的计算,消耗CPU资源,好比计算圆周率、对视频进行高清解码等等,全靠CPU的运算能力。这种计算密集型任务虽然也能够用多任务完成,可是任务越多,花在任务切换的时间就越多,CPU执行任务的效率就越低,因此,要最高效地利用CPU,计算密集型任务同时进行的数量应当等于CPU的核心数。

计算密集型任务因为主要消耗CPU资源,所以,代码运行效率相当重要。Python这样的脚本语言运行效率很低,彻底不适合计算密集型任务。对于计算密集型任务,最好用C语言编写。

第二种任务的类型是IO密集型,涉及到网络、磁盘IO的任务都是IO密集型任务,这类任务的特色是CPU消耗不多,任务的大部分时间都在等待IO操做完成(由于IO的速度远远低于CPU和内存的速度)。对于IO密集型任务,任务越多,CPU效率越高,但也有一个限度。常见的大部分任务都是IO密集型任务,好比Web应用。

IO密集型任务执行期间,99%的时间都花在IO上,花在CPU上的时间不多,所以,用运行速度极快的C语言替换用Python这样运行速度极低的脚本语言,彻底没法提高运行效率。对于IO密集型任务,最合适的语言就是开发效率最高(代码量最少)的语言,脚本语言是首选,C语言最差。

异步IO

考虑到CPU和IO之间巨大的速度差别,一个任务在执行的过程当中大部分时间都在等待IO操做,单进程单线程模型会致使别的任务没法并行执行,所以,咱们才须要多进程模型或者多线程模型来支持多任务并发执行。

现代操做系统对IO操做已经作了巨大的改进,最大的特色就是支持异步IO。若是充分利用操做系统提供的异步IO支持,就能够用单进程单线程模型来执行多任务,这种全新的模型称为事件驱动模型,Nginx就是支持异步IO的Web服务器,它在单核CPU上采用单进程模型就能够高效地支持多任务。在多核CPU上,能够运行多个进程(数量与CPU核心数相同),充分利用多核CPU。因为系统总的进程数量十分有限,所以操做系统调度很是高效。用异步IO编程模型来实现多任务是一个主要的趋势。

对应到Python语言,单进程的异步编程模型称为协程,有了协程的支持,就能够基于事件驱动编写高效的多任务程序。咱们会在后面讨论如何编写协程。

相关文章
相关标签/搜索