首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >戈朗的“所有猩猩都睡着了-死锁!”背后的算法是什么,错误?

戈朗的“所有猩猩都睡着了-死锁!”背后的算法是什么,错误?
EN

Stack Overflow用户
提问于 2018-05-13 17:24:01
回答 2查看 438关注 0票数 3

运行时是否保留一个有向图,表示哪个goroutine在哪个地方等待?如果是的话,你能告诉我源代码中的相关位置吗?

我没有专业的编码围棋,但注意到它有几个很好的特点,当我玩它。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-13 21:43:16

您可以检查Go源代码并很容易发现:它发生在这一功能中,在程序可能进入死锁状态的不同地方都会调用它。

相关的部分是运行时获取开放OS线程的数量,并检查其中有多少实际正在运行代码。还有几张支票,但基本上就是这样。每当您运行阻塞操作(例如,当互斥锁在其他地方时锁定,或者从空通道接收时),调度程序将尝试让线程执行另一个goroutine的工作。如果找不到,则进入空闲状态。

基本上,调度程序总是试图找到等待运行的代码。如果找不到,那就是死锁了。

当然,这不包括运行time.Sleep的goroutines的情况,尽管它们“空闲”,但是有一个线程在准备运行时主动检查它们。换句话说,它们不依赖于程序的其他部分来重新开始“可运行”(就像互斥一样)。

票数 4
EN

Stack Overflow用户

发布于 2018-05-13 21:19:21

Short:运行时调度程序负责在goroutines之间共享OS线程的执行时间,它认识到所有goroutines都在等待或等待其他goroutines,并结束了一个死锁。

想象一下这样的场景: goroutine A从互联网上获取页面,然后通过C频道发送到goroutine B。Goroutine A在goroutine B发送到C频道之前没有什么关系,所以goroutine A在等待goroutine A时睡着了。Goroutine B被阻止等待一个系统调用(HTTP请求)来完成,因此goroutine B没有等待其他的goroutine。现在,如果您插入任何使goroutine B在其他goroutine上等待的操作(比如从D频道接收),goroutine B就会进入睡眠状态,而且由于其他所有的goroutine(实际上就是goroutine A)都已经睡着了,我们就得出了一个死锁。

阅读Go调度程序

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50318730

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档