进程线程与协程

进程线程与协程

程序

最初的计算机没有进程、线程、并发这些概念。最初的计算机更接近一个计算机或者算盘:一边接受输入的计算指令,一边给出输出,指令以带孔纸带的形式输入。如果要执行某个计算任务,首先把任务分解成一系列计算机指令,然后根据指令和孔的对应关系打纸带。再把纸带输到计算机里,计算机就可以执行上面的任务。这一个计算任务,或者说这一卷纸带,就是一个程序。这时的计算机一次只能执行一个程序。

分时调度与并发

现在我们都知道CPU的速度远大于外部设备的速度。这种情况很早就出现了,比如纸带的输入速度逐渐变成整个计算速度的瓶颈。很自然的,为了充分利用CPU的计算性能,我们会想到把输入(IO操作)和CPU计算分开。纸带输入时,指令序列(程序)进入一个缓存系统暂时存放起来。CPU从这个缓存系统里选择要执行的程序。这样缓存系统里可以存放多个程序,CPU得到更充分的利用。同时,有了多个程序自然会有调度的问题,进程的概念就是为了讨论调度产生的,它是资源调度的单位。虽然我们的问题是调度不同的程序,但是有了进程的概念后,我们就可以脱离程序,单独的考虑调度的问题。这种操作在计算机里很常见。最后胜出的策略是CPU分时复用,多进程抢占CPU资源。大概意思是,某个进程A在运行的时候,也不一定是一直都在使用CPU,它可能会有IO操作,CPU就会空闲。如果CPU空闲了,其他就绪的进程就可以插进来使用CPU,只需要把进程A的中间状态临时保存起来就可以了。这样,虽然任意时刻CPU都被单一进程占用,但是由于频繁的切换,多个进程在“同时”运行着。这种“同时”就是并发。并发足够高,才可以填充IO操作的CPU空闲时间——显然进程越多,所有进程都不使用CPU的概率越小;但是,切换进程是有成本的,过高的并发可能会话太多时间在进程切换上。

并行

后来随着技术的进步又出现了多核CPU。之前进程的调度都是在单核CPU的前提下讨论的,现在有了多核CPU,一个直接的问题就是单个进程如何利用多个CPU核心。这个问题导致了线程概念的产生,线程是比进程更小的调度单位,一个进程可以包含多个线程,相同进程内的线程会共享一些资源。如果一个进程包含多个线程,以线程为单位抢占CPU核心,那么单一进程就可以利用多核。当然,不同核心也可以同时运行不同的进程,这种就是真正的同时,也就是并行。最大并行数是等于CPU核心数的,单个CPU的核心注定有限,如果要提高并行能力,往往需要多台计算机组成机群。

协程

回到单核CPU的情况,为了充分利用CPU,我们可以开多进程或者多线程,防止IO操作时CPU闲置。但是切换进程和线程都需要一定的成本,这个成本能不能进一步降低呢?某个线程A遇到IO后,CPU会闲置,然后被其他线程抢占;线程A的上下文状态会暂存起来,这是无法避免的。那么如果线程A遇到IO后,暂时跳过IO,继续执行后续的需要CPU的计算呢?这样不就可以避免线程的切换了吗?这个思路继续下去,就产生了协程的概念:协程的调度发生在同一个线程内,由线程控制调度。由于切换协程的成本更低,使用了协程以后即使是单线程,并发都可以达到一个很高的量级。redis作为单线程服务并发能力很强,其底层实现——事件循环+IO多路复用,和协程的思路是一致的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值