聊一聊操作系统线程调度与Go协程

本文探讨了操作系统线程调度的基本概念,包括操作系统的作用、线程状态和调度器的工作原理。接着介绍了Go语言中的协程调度,强调了Go协程的轻量级和易切换特性,并通过Map-Reduce示例说明了多协程在特定场景下的优势。文中还提到了Go调度器的P、M和G模型,以及协程的切换和偷窃机制,最后总结了Go协程相对于系统线程的效率优势。
摘要由CSDN通过智能技术生成

前言

我们计算机上面跑的每个任务,都是操作系统层面的资源分配,从启动进程到创建线程,在核数固定的情况下,多线程并发地执行。Go协程是一个比系统线程更细粒度的资源,轻量级和易切换。
这几天看了一些相关的文章,这次尝试从操作系统到Go协程,简单聊聊它们是如何关联上的以及我个人的理解。

基本概念

操作系统(OS)

操作系统负责着底层硬件的调度,它分配CPU,内存,磁盘的资源,并且替我们分配不同线程在不同CPU核的执行,保证各个程序如预期的指令进行执行。我们提交的每个程序,最终都会转换成一系列给操作系统识别的指令。

线程(Thread)

上述经过转换的一系列指令,操作系统会通过线程来帮我们执行,本质上线程是a path of execution,一段可执行的程序路径。
线程有下面三个状态:

  • 运行中:正在执行任务,理想状态是所有线程都处于这个状态。
  • 就绪:可以随时加入运行,从就绪到运行的状态切换,叫做上下文切换,它需要一定的代价。
  • 等待就绪:需要等待资源分配或者IO(网络/设备)阻塞中,需要经过就绪才能运行,这是在用户角度最不想看到的,它成为了程序大部分的性能瓶颈。
系统调度器

调度器肩负着巨大的使命,主要在于调度CPU与线程关系,保证不会有CPU闲下来,想象一下CPU就是仓鼠笼子里面的仓鼠,调度器一旦发现有仓鼠(CPU)在打瞌睡,就推动它们到轮子(线程)上跑,一刻也不能停。毕竟CPU的运算能力是很强悍的,一毫秒的空闲都是巨大的浪费。
往细处说,仓鼠只有4只(四核),哪个轮子(线程)优先跑,取决于轮子(线程)的优先级。调度器肩负着运筹帷幄的使命,既要减少催促仓鼠跑动的延迟,同时还要保证不能有任务一直得不到执行,线程如果一直得不到仓鼠处理被称作“饥饿现象”。

任务类型

不同的任务对系统资源有不同的要求

  • I/O频繁切换
    未雨绸缪,IO指的是Input/Output,输入输出等待。这种等待资源输入/输出的job,主要瓶颈在资源是否分配到位,比如系统调用/文件IO等,其线程切换的时间远远小于IO设备/网络延迟,主要短板在于等待I/O,而不是线程上下文切换,因此可以分配较多线程,在“粮草”还没送到的这段时间,执行作战前的准备。

  • 计算密集型
    这种任务主要耗CPU,比如用一个线程计算圆周率π的第N位。如果分配大量的线程给它,系统既要保证各个线程对计算状态的共享,先不考虑会发生脏读/脏写操作,还需要频繁进行线程切换,这会造成大量时间浪费,线程每次重新唤醒都要在程序计数器(PC)寻找下一个执行指令的位置,在核数固定的情况下,分配过多线程会有事倍功半的效果。

    If your program is focused on CPU-Bound work, then context switches are going to be a performance nightmare. Since the Thead always has work to do, the context switch is stopping that work from progressing.

    当然也有例外的情况,比如Map-Reduce,指的是先拆分后聚合。当你的计算任务可以拆分成很多模块,在各个模块不同执行顺序不会影响最终结果的情况下,尝试“逐个击破”,最终再汇聚的情况,如果能合理分配任务,多线程肯定是优于单线程的。

后面尝试通过列举几个Go的简单程序,通过单/多协程处理,比对两者在不同情景的性能差异情况。

Map-Reduce:

这个例子比较简单,我们目标是累加一个等差数列

var PIXEL_ARRAY []int
//初始化一个等差数列,后面尝试将等差数列传到单协程/多协程函数进行累加
func init()  {
   
	for i := 1; i <= 100000; i++ {
   
		PIXEL_ARRAY = append(PIXEL_ARRAY, i)
	}
}

后面我们用单协程/多协程版本,区分开两个实现方式

//单协程暴力版本
func SumWithSingle(arr []int) int32 {
   
	var sum int32
	//遍历累加,相当暴力!
	for i <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值