为了账号安全,请及时绑定邮箱和手机立即绑定

golang select语句是如何实现的?

golang select语句是如何实现的?

Go
白猪掌柜的 2022-01-10 10:40:05
特别是,我在 C++ 中有一些阻塞队列,我想等到其中任何一个有一些我可以弹出的项目。我能想到的唯一机制是为从其输入队列中弹出并馈送到原始线程可以等待的主队列的每个队列生成一个单独的线程。每次我想从一组队列中弹出时,生成 N 个新线程然后将它们全部杀死似乎是一种资源沉重。Golang 是否实现了一些我可以在自己的 C++ 代码中实现的更优雅的机制?
查看完整描述

2 回答

?
UYOU

TA贡献1878条经验 获得超4个赞

我不一定会说 Go 的select实现很优雅,但我认为它以自己的方式很漂亮,并且经过了相当优化。

  • select使用单个非默认情况对 s 进行特殊处理

  • 它改变了评估案例的顺序,以避免确定性饥饿

  • 它对寻找已经满意的案例进行了乐观的第一次审核

  • 它使用许多内部的,只有运行时机制知道的在每个通道的内部发送者/接收者队列中排队

    • 它使用的sudogs 类似于轻量级 goroutine 引用(sudog同一个 goroutine可以有多个s),允许快速跳转到 goroutine 堆栈

    • 它使用调度程序的gopark机制来阻止自己,从而允许有效地取消停放信号

    • 当发出信号并取消驻留时,它通过操纵selectgoroutine 的程序计数器立即进入触发的案例处理函数

实施中没有单一的总体突破性想法,但您会非常欣赏如何仔细修改每个步骤,使其快速、高效并与渠道概念很好地集成。正因为如此,select用另一种语言重新实现 Go 的语句并不是很容易,除非你至少先有chan构造。

您可以查看其他语言中可用的重新实现,其中的想法以不同程度的相似性和有效性重做。如果我必须select用另一种语言从头开始重新实现,我可能会首先尝试一个共享信号量,如果这不起作用,则切换到一个更粗略的、稍微休眠然后签入随机顺序战略。


查看完整回答
反对 回复 2022-01-10
?
慕后森

TA贡献1802条经验 获得超5个赞

Golang 的select声明灵感来自 Cselect函数(参见 GNU libc文档),该函数用于在一组文件描述符上等待 I/O。如果您的队列使用套接字或管道进行通信,您可以使用它。


查看完整回答
反对 回复 2022-01-10
  • 2 回答
  • 0 关注
  • 167 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信