聊聊Goroutine-线程模型与调度器(一)

161 篇文章 12 订阅

goroutine是Go实现的用户态线程,主要用来解决操作系统线程太【重】的问题。

操作系统线程的重,主要体现在以下两方面:

  1. 创建和切换。操作系统线程的创建和切换操作都需要进入内核,而进入操作系统内核性能代价较高,开销较大。

  2. 内存使用。其一是内核为了避免极端情况下操作系统线程栈溢出,所以在创建线程时,会为其分配一个较大的栈内存(虚拟地址空间,内核并不会一开始就分配这么多物理内存),大多数情况下操作系统线程远远用不了这么多内存,这就导致了内存浪费,另外一点就是栈内存空间一旦创建和初始化完成后,其大小就不能再产生变化,这导致了在某特殊环境下线程栈还是有溢出的风险。

用户态的goroutine的【轻】则体现在如下两个方面:

  1. goroutine是用户态线程,创建和切换都在用户状代码中完成,而无需进入系统内核,所以其开销要远小于系统线程的创建和切换。

  2. goroutine启动时栈大小默认为2K,大多数情况下是够用的,如果不够的话,goroutine的栈会自动扩大,同时,如果栈内存太大过于浪费,还能自动收缩,如此既没有栈溢出的风险,也不会造成栈内存空间过大的浪费。

正是因为如上原因,使得Go程序中可轻易创建很多goroutine来并发执行任务,而不用过多考虑性能和内存的问题。

来看下goroutine的线程模型,之后简单介绍下goroutine调度器的。

goroutine建立在系统线程之上,与系统线程实现了多对多(M:N)的两级线程模型。

这时的M:N指的是M个goroutine运行在N个系统线程之上,内核负责对这N个系统线程进行调度,而这N个系统线程又负责对这M个goroutine进行调度和运行。

系统线程对goroutine的调度指的是程序代码按照一定算法在一定时间挑选出合适的goroutine并放到CPU上运行的过程。

这些负责负责对goroutine进行调度的程序代码称之为goroutine调度器。

来看下goroutine调度器工作的伪代码:

// 程序启动时的初始化代码......for i := 0; i < N; i++ { // 创建N个操作系统线程执行schedule函数    create_os_thread(schedule) // 创建一个操作系统线程执行schedule函数}//schedule函数实现调度逻辑func schedule() {   for { //调度循环         // 根据某种算法从M个goroutine中找出一个需要运行的goroutine         g := find_a_runnable_goroutine_from_M_goroutines()         run_g(g) // CPU运行该goroutine,直到需要调度其它goroutine才返回         save_status_of_g(g) // 保存goroutine的状态,主要是寄存器的值    }}

上述代码意为程序运行起来之后创建了N个由内核调度的系统线程,也可以称为工作线程,来执行schedule,而schedule在一个调度循环中反复从M个goroutine中挑选出一个需要执行的goroutine,并跳转到goroutine去执行,直到需要调度其它goroutine时才返回到schedule中通过save_status_of_g保存刚刚正在运行的goroutine的状态,然后再去寻找下一个goroutine。

上述代码为高度抽象且做了修改和简化,只是为了帮助宏观理解goroutine两级调度模型,具体的实现原理和细节在下篇文章中会慢慢聊。

以上仅为个人观点,不一定准确,能帮到各位那是最好的。

好啦,到这里本文就结束了,喜欢的话就来个三连击吧。

扫码关注公众号,获取更多优质内容。

  

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luyaran

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值