go和rust的协程模型

协程

协程是一种可以调度的计算单元,它和线程有很多相似的地方:可以被挂起和恢复,有自己的运行上下文。比较大的一个不同之处在于:协程的调度发生在用户态,由用户态程序来控制和管理,而线程则是由OS直接调度的。多个协程可以都在一个线程上运行,他们的运行过程是并发的,但并不能真正的并行执行。由协程调度程序来切换各个协程的运行,使它们表现得像同时在执行。

简单的说,协程就是轻量级的线程,使用协程的主要目的就和使用多线程的目的一样,提高程序的性能,增加cpu的使用率。

go语言中的协程模型

go语言被设计为天生支持协程,在代码中使用 go 关键字就能启动一个goroutinue,也就是协程。go的runtime两大主要职责:一个是垃圾回收,另一个就是调度协程。 go的协程调度模型可以称作GMP模型,其中:

  • G 表示 goroutinue,也就是协程
  • M 表示 os thread
  • P 表示调度上下文,每个M必须要先获取一个P,才能够开始执行G。

最初的调度模型中没有P的概念,在1.1版本后,go的调度器中引入了P,这么做主要是为了提升调度的性能,尽力的保证每个可运行的G都能够尽快运行。调度机制主要特点如下:

  • 每个P都有一个可运行的G队列
  • 另外有一个全局的可以运行G队列
  • M获取到P后,从P的运行队列中获取G来运行
  • 如果P本地的运行队列为空,则尝试从全局队列中获取G来运行
  • 如果全局的运行队列也为空,则尝试从其他P的运行队列中获取G

每个G运行的时间是由调度器来控制的,不会出现让某个G一直运行,而让其他G长时间的等待。如果M在运行G的时候发生了阻塞,比如block在某个系统调用,M则也会被阻塞住,P的本地队列会调度到其他M上执行。

P的数量可以通过GOMAXPROCS函数来设置,因为每个M对应一个P,因此这个函数也可以认为是设置了go程序最大的线程数量。(注意,M是可以大于P的,例如:一个M阻塞住了,那么正在运行的M数目还是和P的数目一样,这样总的M数目就大于P了。)

rust 中的协程模型

rust语言本身没有支持协程,它没有runtime,也就不能做调度,gc这样的事情。不过rust提供了一些定义好的trait,如Future,可以用来实现协程。在rust中使用协程主要是通过tokio 包,tokio是一个用于异步编程的包,它的实现包括一个task系统,一个runtime,以及异步编码的一些基本库。

在tokio中,可以认为task就是协程,由tokio runtime调度执行。task有两个非常重要的特点:

  • task不会阻塞,它是全异步的
  • task的执行不会被打断,也就是如果task不主动让出,是不会被切换走的

如果一个task中依赖了某个底层资源,runtime执行这个task的时候,根据底层资源是否ready,可以分为两种情况处理:1,底层资源已经ready,那么task可以立即返回需要的结果;2,底层资源还没有准备好,那么task返回NotReady,并再次进入调度队列。task系统此时会记录下这个task和相应底层资源的关系,等到底层资源ready后,会再次将task交给runtime来执行。

如果task中没有依赖底层资源,runtime执行这个task的时候,会立即返回结果。需要注意的是,如果task中的计算逻辑过重,占用cpu时间过长,会影响到其他task的执行。因为tokio的runtime没有给task分配执行时间片,而是会一直将这个task执行完成,这个过程中,其他的task可能会长时间得不到执行,这是一种非预期的情形。这也是为什么task中不能写太重的计算逻辑的原因。

在使用tokio时,可以选择使用哪种类型的runtime,主要有两种:local thread 和 threadpool,也就是单线程和多线程的区别。

对比

比较go和rust中的协程实现来看,go的协程模型相对来说更好理解,可以类比OS调度线程的机制。由于goroutinue是可以阻塞的,只要某个goroutinue阻塞了,就将剩余可运行的goroutinue调度到其他线程上执行。

而rust的tokio则是一个异步的执行框架,task是异步非阻塞的,并且task的执行不可抢占。它和nginx,libevent,redis的运行机制更相似,但多了task这个概念,整个调度的机制显得更复杂。

参考

http://morsmachine.dk/go-scheduler

https://docs.google.com/document/d/1TTj4T2JO42uD5ID9e89oa0sLKhJYD0Y_kqxDv3I3XMw

https://tokio.rs/docs/internals/runtime-model/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • 进程时代 后来,现代化的计算机有了操作系统,每个程序都是一个进程,但是操作系统在一段时间只能运行一个进程,直到这个...
    大学渣PG阅读 1,890评论 0 1
  • 阅读Go并发编程对go语言线程模型的笔记,解释的非常到,好记性不如烂笔头,忘记的时候回来翻一番,在此做下笔记。 G...
    WithLin阅读 1,074评论 0 4
  • 模型概述 1 .每一个os线程都有一个固定各大小的内存块来做栈,这个栈会用来存储当前正在被调用或者挂起的的函数内部...
    skoll阅读 1,021评论 0 0
  • 进程、线程和协程 进程的定义: 进程,是计算机中已运行程序的实体。程序本身只是指令、数据及其组织形式的描述,进程才...
    星丶雲阅读 1,370评论 2 14
  • 一、聊聊并发这件事 在基础系列我们学习了Go的并发编程,对并发的概念已经有了一定的了解。在各种现代高级语言中,对并...
    GoFuncChan阅读 2,257评论 0 4