进程 vs 线程

- 描述

要实现多任务,通常会设计Master-Worker模式,Master负责分配任务,Worker负责执行任务。

多环境任务下,通常是一个Master,多个Worker

多进程最大的优点就是稳定性高,因为一个子进程崩溃了,不会影响主进程和其他子进程。缺点是创建进程的代价大,在Windows下创建进程开销巨大。

多线程模式通常比多进程快一点,但是也快不到哪去,而且多线程模式致命的缺点就是任何一个线程挂掉都可能直接造成整个进程崩溃,因为所有线程共享进程的内存。

在Windows下,多线程的效率要比多进程要高

- 线程切换

无论是多线程还是多进程,只要数量一多,效率肯定上不去

假设每天晚上需要做语文、数学、英语、物理、化学者五科作业,每项作业耗时1小时。

如果先花1小时做语文作业,做完了,再花1小时做数学作业,以此类推将所有作业做完,共计5小时。这种方式称为单任务模型,或者批处理任务模型。

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

但是,切换是有代价的,比如从语文奇幻到数学,要先收拾桌子上的语文淑文、钢笔(保留现场),然后,打开数学课本、找出圆规直尺(准信新环境),才能开始做数学作业。

操作系统再切换进程或者线程时也是一样的,它需要先保留当前执行的现场环境(CPU寄存器状态、内存页等),然后,把新任务的过程环境准备好(恢复上祠的寄存状态、切换内存页等),才能开始执行。

这个切换过程虽然很快,但是也需要耗费时间。如果有几千个任务同时进行,操作系统可能就主要忙着切换任务,根本没有多少时间去执行任务了,这种情况最常见的就是硬盘狂响,点窗口无反应,系统处于假死状态。

- 计算密集型 vs IO密集型

任务分为计算密集型和IO密集型

计算密集型

计算密集型任务的特点是要进行大量的计算,消耗CPU资源,比如计算圆周率,对视频进行高清解码等等,全靠CPU的运算能力。

计算机莫季星任务虽然可以用多任务完成,但是任务越多,花在任务切换的时间就越多,CPU执行任务的效率就越低。

要高效地利用CPU,计算密集型任务同时即兴的数量应当等于CPU的核心数。

计算密集型任务由于主要消耗CPU资源,因此,代码运行效率至关重要,最好用C语言编写。

IO密集型

涉及到网络、硬盘IO的任务都是IO密集型任务,这类任务的特点是CUP消耗很少,任务的大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU的内存的速度)。

对于IO密集型任务,任务越多,CPU效率越高,不过也是有限度的。

IO密集型任务执行起就按,99%的时间都花在IO上,花在CPU上的时间很少。因此,最适合的语言就是开发效率最高(代码量最少)的语言,脚本语言是首选。

- 异步IO

由于CPU和IO之间巨大的速度差异,一个任务在执行的过程中大部分时间都在等待IO操作,单进程单线程模型会导致别的任务无法并行执行。

现代操作系统支持异步IO,充分利用异步IO支持,用单进程单线程来执行多任务,这种全新的模型称为事件驱动模型。

Nginx就是支持异步IO的Web服务器,它在单核CPU上采用单进程模型就可以高效地支持多任务。在多个CPU上,可以运行多个进程(数量与CPU核心数相同),充分利用多个CPU。

对应到PYthon语言,单线程的异步编程模型称为协程