如何实现golang select语句?

时间:2016-05-04 07:29:48

标签: c++ multithreading go

特别是,我在C ++中有一些阻塞队列,我想等到其中任何一个都有一些我可以弹出的项目。

我能想到的唯一机制是为每个从其输入队列弹出的队列生成一个单独的线程,并将其提供给原始线程可以等待的主队列。

每当我想从一组队列中弹出时,产生N个新线程然后杀死所有线程似乎有点资源。

Golang是否实现了一些我可以在自己的C ++代码中实现的更优雅的机制?

2 个答案:

答案 0 :(得分:5)

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

  • 使用单个非默认情况
  • 特殊处理select
  • 它排列评估案例的顺序以避免确定性饥饿
  • 它首先对那些已经满足的案件进行了乐观的首次传递
  • 它使用许多内部的每个通道的内部发送器/接收器队列排队,只有运行时机制才知道
    • 它使用sudog s,就像轻量级goroutine引用一样(可以有很多sudog用于相同的goroutine),允许快速跳转到goroutine堆栈
    • 它使用调度程序的gopark机制来阻止自身,从而有效地解除对信号的停放
    • 发出信号并取消停放时,它会立即通过操纵select goroutine程序计数器进入触发案例处理函数

在实施过程中没有一个突出的开创性理念,但您真的很感激每个步骤都经过精心修改,以便快速,高效并与渠道概念完美融合。因此,除非你至少先拥有select构造,否则用其他语言重新实现Go chan语句并不是一件容易的事。

您可以查看其他语言中可用的重新实现,其中的想法是重做的,具有不同程度的相似性和有效性。如果我不得不用另一种语言从头开始重新实现select,我可能会首先尝试一个共享的信号量,如果没有工作,请切换到一个较小的,睡觉 - 一点点 - 然后 - 签入随机顺序策略。

答案 1 :(得分:-1)

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