标签:系统 alt shell from 相同 入口 头部 中断 技术
引自我在知乎上的回答:进程 线程 协程 例程 过程 的区别是什么? - 骏马金龙的回答 - 知乎
首先解释下程序、进程、上下文切换和线程。然后再解释协程、例程、过程。
程序:源代码堆起来的东西。相当于一个一动不动没有生命的机器人。
进程:程序在系统上跑起来(运行)之后的东西(动态的)。相当于有了生命的机器人。生命是内核给的,动起来的能力是CPU提供的驱动力。
上下文切换:在某一时刻,一核CPU只能执行一个进程。相当于内核只能让一核CPU为一个机器人提供驱动力让它动起来(1:1),多核CPU可以同时为多个机器人提供驱动力。
线程:一个进程内可以有多个执行线程,或者说线程是进程内部的小型进程。相当于在机器人内部根据机器人自身克隆了很多个基本完全相同的体内小机器人。
现在,对比一下多进程和多线程?
然后是协程、例程、过程。但是在解释这个之前,先解释下现在更为俗知的函数,以及它们和进程、线程之间的关系。
函数:一种代码段。用来表示一个要完成的任务单元。当然,这个任务里可能也包含了其它多个子任务。
再说程序:
先总结一下重点:进程、线程是机器人,函数是机器人要干的活。
机器人是怎么执行函数的呢?在不使用coroutine(也就是国人翻译后的"协程")的情况下,它的执行流程是固定的:从main函数开始,跳转执行其它函数A,main函数被搁置等待,它必须等待跳转后的函数A执行完返回后才能回到main函数继续向下执行,如果函数A中还有调用函数B,那么函数A被搁置等待,它必须等待函数B执行完返回后才继续向下执行。直到main函数也执行完,程序退出。
继续用机器人来比喻,那就是机器人要执行一个任务,但这个任务中要求临时去执行另一个任务,那么这个机器人必须先去执行另一个任务,并只能在执行完另一个任务的时候回到之前的那个任务继续执行。
所以,重点是:函数A中在第X行开始跳转调用函数B时,函数A必须等待函数B执行完返回后才能继续从第X行处开始继续向下。
回到正题要解释的东西:协程、例程、过程。
很遗憾,例程、过程、子程序,它们都是函数的不同称呼,不同的时代、不同的编程语言称呼的方式不一样,都是任务单元。甚至面向对象里的方法也是函数,只不过在面向对象的面具之下,它有一些和面向对象相关的特性。
最后是协程。我猜你说的协程应该是coroutine这类东西,全称是cooperative routine,也叫做cooperative tasks。只看英文的话,意思已经很明显了:协同运行的子程序(子程序就是例程、函数、过程)。或者说是协同执行的任务。
在解释coroutine之前,多插一句嘴。
coroutine被翻译为协程,个人认为是不太合理的。在shell中有coproc的概念(ksh/bash等一些shell都支持coproc的功能),cooperative process,表示协同运行的进程,按单词字面意思,这才应该被翻译为协程。
协同运行?这是个什么意思。回顾下刚才解释函数(因为是co routine,所以我下面全部用routine来替换函数的说法)的执行流程在理解协同运行是什么意思。
在正常情况下,routine跳转运行后必须原地等待跳转后的那个routine执行完返回才能继续从原地向下执行。
但是,使用coroutine的时候,假设routine1和coroutine2互为coroutine,那么routine1跳转到routine2去执行的时候,它会等待routine2才能继续向下执行,但是不一定是等待routine2执行完,也可能是等待routine2重新跳转回routine1(因为routine2已经产生了一些可以让routine1继续运行的数据,而不是让routine1继续在那里阻塞)。同理routine2也可能会原地等待routine1,routine1再跳回routine2。
但是这怎么行,来来回回的跳转总得退出吧?这就是跟所写的代码有关系了。比如某个routine中加入一个判断,达到某一条件时就不再跳转,而是直接向下执行。
机器人的比喻又来了。机器人要执行一个任务,但要求临时去执行另一个任务,现在不强制规定必须执行完另一个任务才回来执行原始任务,而是可以在执行另一个任务的时候,又临时回来执行原始任务。
如果说不好理解,那么下面这个wiki中给的生产者消费者模型的伪代码很容易帮助理解coroutine,这个程序不一定合理,但非常适合于理解"协同"的意义。其中q
是一个队列,生产者coroutine会跳转到消费者coroutine,同理消费者coroutine也一样会跳转到生产者coroutine。
var q := new queue
coroutine produce
loop
while q is not full
create some new items
add the items to q
yield to consume
coroutine consume
loop
while q is not empty
remove some items from q
use the items
yield to produce
这就是协同运行以及coroutine的解释,我想应该已经不难理解了。
最后,说一下coroutine的优点:
实际上,coroutine可以认为是单线程多任务的工作方式(当然,进程中实现coroutine也是可以的),因为它在单个线程中的多个任务之间直接跳转,而多线程是通过上下文切换来实现多任务的。换句话说,coroutine提供了并发却不并行的功能。通过coroutine,还能实现更为"实时"的上下文任务,因为coroutine之间的跳转切换不需要任何系统调用和可能的阻塞调用,不需要像多线程一样为了线程之间的资源同步而使用额外的互斥锁、信号量等。
标签:系统 alt shell from 相同 入口 头部 中断 技术
原文地址:https://www.cnblogs.com/f-ck-need-u/p/10802716.html