首页 > 编程语言 >《高级程序员 面试攻略 》go抢占式调度 通俗拟人解释

《高级程序员 面试攻略 》go抢占式调度 通俗拟人解释

时间:2023-08-15 09:36:37浏览次数:41  
标签:执行权 抢占 拟人 Goroutine 音乐家 式调度 任务 go 卡顿

当我们谈论 Go 语言的抢占式调度时,可以使用一个通俗的拟人解释来描述它的工作原理。

假设你正在组织一场音乐会,有许多音乐家需要在舞台上演奏乐器。你作为指挥,负责协调他们的演奏。每个音乐家都是一个 Goroutine(Go 协程),而你是调度器(Scheduler)。

在开始音乐会之前,你将每个音乐家的乐器准备好,并让他们准备好演奏的乐谱。然后,音乐会开始了。

你站在舞台旁边,同时关注每个音乐家的演奏。当某个音乐家的演奏时间到了(比如他的乐谱时间片段用完了),你会迅速把指挥棒交给下一个音乐家,让他继续演奏。这就是抢占式调度。

无论是因为时间片段用完,还是因为某个音乐家主动让出指挥棒(比如他在等待某些资源时),你都会迅速将指挥棒交给下一个等待演奏的音乐家。这样,每个音乐家都有机会按照既定的演奏顺序进行演奏,而不会因为某个音乐家长时间霸占指挥棒而导致其他音乐家无法演奏。

这种抢占式调度保证了每个 Goroutine 都有公平的执行机会,防止某个 Goroutine 长时间占用 CPU 而导致其他 Goroutine 无法进行。调度器会根据一定的策略(如时间片轮转)切换 Goroutine 的执行,使得它们能够以一种看起来并行执行的方式运行。

通过这个拟人化的比喻,我们可以更好地理解 Go 的抢占式调度机制,它类似于一个指挥在音乐会上快速交替指挥不同的音乐家,以确保每个音乐家都能有机会进行演奏,并且整场音乐会能够连续进行下去。

 

 

那如果上一个音乐家的任务没有完成,被抢占了怎么办

 

如果上一个音乐家的任务没有完成就被抢占了,那么被抢占的音乐家会被暂停,并且保存它的执行状态,等待下一次调度器再次将执行权交给它时继续执行。

在 Go 的抢占式调度中,调度器会根据一定的策略(如时间片轮转)决定何时切换 Goroutine 的执行。当一个 Goroutine的时间片用完或者它主动让出执行权(比如在等待某些资源时),调度器会将执行权交给下一个等待执行的 Goroutine。

如果上一个音乐家的任务没有完成,但是时间片用完了或者它主动让出了执行权,调度器会将执行权切换到下一个等待执行的 Goroutine。这样,被抢占的音乐家的执行会暂停,并且它的执行状态会被保存下来,以便下次再次执行时能够从中断的地方继续执行。

当下一次调度器再次将执行权交给被抢占的音乐家时,它会从之前保存的执行状态处继续执行,好像从未被中断过一样。这种方式保证了每个 Goroutine 都能有公平的执行机会,而不会因为某个 Goroutine 长时间占用 CPU 而导致其他 Goroutine 无法执行。

因此,即使被抢占了,上一个音乐家的任务仍然会在合适的时候继续执行,而不会被完全丢弃或忽略。这种抢占式调度机制确保了并发的公平性和效率。

 

 

如果每次这个音乐家都卡顿怎么办

 

 

如果某个音乐家的任务每次都卡顿,导致其他音乐家无法得到执行机会,那么这可能是一个问题,需要进行一些调整和排查。

以下是一些可能的解决方案和排查步骤:

1. 优化音乐家的任务:检查卡顿的原因是什么,可能是因为任务中存在耗时操作、死循环或者资源竞争等问题。尝试优化任务的算法或者使用异步操作等方法来减少卡顿情况。

1. 分解任务:如果某个音乐家的任务过于庞大,可以考虑将其分解为更小的子任务。这样可以避免一个任务长时间占用执行权,使得其他任务得到执行的机会。

1. 调整调度策略:调度器的策略可能会影响卡顿情况。可以尝试调整调度策略,使得调度器更频繁地切换到其他任务,从而避免某个任务长时间占用执行权。

1. 使用超时机制:在任务中引入超时机制,如果某个任务长时间没有完成,可以终止该任务并切换到其他任务。这样可以避免卡顿任务长时间占用执行权。

1. 并发限制和资源管理:如果卡顿是因为资源竞争导致的,可以考虑引入并发限制或者资源管理机制,以确保每个任务都能够合理地使用资源,避免资源争用导致的卡顿情况。

1. 监控和日志记录:在应用程序中添加监控和日志记录,以便及时发现和排查卡顿问题。通过收集和分析相关的性能数据,可以更好地理解卡顿的原因,并采取相应的优化措施。

综上所述,如果某个音乐家的任务每次都卡顿,需要仔细排查问题的原因,并采取相应的优化措施。通过优化任务、调整调度策略、引入超时机制等方法,可以避免一个任务长时间占用执行权,保证其他任务能够得到执行的机会,从而提高整体的并发性和性能。

标签:执行权,抢占,拟人,Goroutine,音乐家,式调度,任务,go,卡顿
From: https://www.cnblogs.com/lingmou/p/17630468.html

相关文章

  • 《高级程序员 面试攻略 》通俗拟人解释 swoole的协程 和 go的协程有什么区别
    Swoole的协程和Go的协程(Goroutine)都是用于实现轻量级并发的机制,但它们有一些区别。1.语言和环境:Swoole协程是在PHP语言中实现的,而Go协程是在Go语言中实现的。因此,它们在语言和运行时环境上存在差异。1.编程模型:Swoole协程使用的是“同步风格”的编程模型,类似于传统......
  • 学习go语言编程之网络编程
    Socket编程Golang语言标准库对Socket编程进行了抽象,无论使用什么协议建立什么形式的连接,都只需要调用net.Dial()即可。Dial()函数Dial()函数的原型如下:funcDial(network,addressstring)(Conn,error)参数含义如下:network:网络协议名字,如:tcp,udp等Dial()函数支持的网络......
  • 学习go语言编程之并发编程
    并发基础并发包含如下几种主流的实现模型:多进程多线程基于回到的非阻塞/异步IO协程协程与传统的系统级线程和进程相比,协程最大的优势在于“轻量级”,可以轻松创建上百万个而不会导致系统资源枯竭,而线程和进程通常最多不超过1万个。Golang在语言级别支持协程,叫goroutine。......
  • Paper Reading: A pareto-based ensemble of feature selection algorithms
    目录研究动机文章贡献相关概念集成特征选择帕累托最优非支配排序拥挤距离本文方法实验结果数据集和实验设置与FS方法比较与集成FS方法比较优点和创新点PaperReading是从个人角度进行的一些总结分享,受到个人关注点的侧重和实力所限,可能有理解不到位的地方。具体的细节还需要......
  • Go 语言并发
    启动单个goroutinepackagemainimport( "fmt" "time")funchello(){ fmt.Println("hello")}funcmain(){ gohello() fmt.Println("欢迎来到编程狮") time.Sleep(time.Second)}sync.WaitGrouppackagemainimport( "fmt" &qu......
  • Go 错误处理
     Go语言通过内置的错误接口提供了非常简单的错误处理机制。error类型是一个接口类型typeerrorinterface{Error()string}packagemainimport("fmt")//定义一个DivideError结构typeDivideErrorstruct{divideeintdividerint}//实现`error`......
  • Go 语言反射(Reflect)
    Go语言提供了一种机制,在不知道具体类型的情况下,可以用反射来更新变量值,查看变量类型Typeofpackagemainimport( "fmt" "reflect")funcmain(){ varbooknumfloat32=6 varisbookbool=true bookauthor:="www.w3cschool.cn" bookdetail:=make(map[string]string) bo......
  • 13 桥接模式 -- go语言设计模式
    桥接模式是将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(HandleandBody)模式或接口(interface)模式。桥接模式的实现代码packagemainimport"fmt"//发送信息的具体实现(操作)typeMessageImplementerinterface{ send(test,......
  • 让 GPT-4 来修复 Golang “数据竞争”问题 - 每天5分钟玩转 GPT 编程系列(6)
    目录1.Golang中的“数据竞争”2.GoPool中的数据竞争问题3.让GPT-4来修复数据竞争问题3.1和GPT-4的第一轮沟通3.2和GPT-4的第二轮沟通3.3提交代码4.总结1.Golang中的“数据竞争”我在上个月发过一篇《跟着GPT-4从0到1学习Golang并发机制(三)》,文中有一节专......
  • E. Maximum Monogonosity
    E.MaximumMonogonosityYouaregivenanarray$a$oflength$n$andanarray$b$oflength$n$.Thecostofasegment$[l,r]$,$1\lel\ler\len$,isdefinedas$|b_l-a_r|+|b_r-a_l|$.Recallthattwosegments$[l_1,r_1]$,$1\lel_1\ler......