Golang-调度器原理解析

本文深入探讨了Golang调度器的由来,从单进程到多进程/多线程再到协程的发展。重点介绍了GPM模型的Go调度器,包括goroutine、调度器设计思想、工作窃取机制以及M0和G0的作用。文章还讨论了P和M的数量问题,展示了启动goroutine的调度流程,强调了Go如何通过协作调度和复用线程实现高效的并发执行。
摘要由CSDN通过智能技术生成

Golang调度器原理解析

本文主要介绍调度器的由来以及golang调度器为何要如此设计,以及GPM模型解析

一.调度器的由来

1.单进程时代

单进程时代不需要调度器,一切程序都是串行,所以单进程的操作系统会面临这样一个问题:

  • 程序只能串行执行,一个进程阻塞了,其他进程啥事也做不了,只能等待,会造成CPU时间的严重浪费

那么能不能有多个进程一起来执行多个任务呢?
答案是可以的,后来操作系统就有了最早的并发能力:多进程并发多进程并发:当一个进程阻塞的时候,切换到另外等待执行的进程,尽量将CPU利用起来。

2.多进程/多线程时代

多进程或多线程时代就有了调度器的需求,以多进程为例,其会使用CPU调度器来当某个进程阻塞的时候,调度一个合适的进程给CPU。

这种方式解决了阻塞的问题,但也存在一个问题:

  • 如果进程数量很多,进程的调度会占用CPU很多的时间(进程创建,销毁,切换等),CPU利用率不高

对比线程,虽然其调度成本会比进程小很多,但实际上多线程程序的开发和设计也比较复杂,而且在当前互联网业务环境下,为每个任务都创建一个线程是不现实的,这会大量的消耗内存(进程占用4G(32位),而线程大约也要4M)
所以,多线程/多进程时代,会面临这样两个问题

  • 高内存占用
  • 调度的高CPU消耗

但是,其实一个线程可以分为内核态线程用户态线程一个用户态线程必须要绑定一个内核态线程,但是CPU并不知道用户态线程的存在,它只知道它运行的是一个内核态线程(Linux的PCB进程控制块)

3.协程时代

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值