2016-05-04 41 views
4

特别是,我在C++中有一些阻塞队列,我想等到他们中的任何一个有一些我可以弹出的项。golang select语句如何实现?

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

似乎种类繁多的资源会产生N个新线程,然后每当我想从一组队列中弹出时全部杀死它们。

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

+0

我不认为你可以使用标准设施在一个线程中等待多个条件变量。也许你可以颠倒这个问题,并让队列主动进入他们通知现在阻塞线程的“主”队列。 – melak47

+1

Go的select实现是[here](https:// github。com/golang/go/blob/master/src/runtime/select.go),也许它可以给你一些想法。 –

+0

https://github.com/tylertreat/chan –

回答

-1

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

4

我不一定会说Go的select实现是优雅的,但我认为它很美丽,并且它是相当优化的。

  • 它特殊的手柄select s的单一非默认情况下
  • 它的置换在哪些情况下是为了评估,以避免
  • 它不乐观的第一传过来的情况下,寻找确定性饥饿的顺序一个这是已经满足
  • 它使用许多内部排入上各通道的内部发送器/接收器队列,只知道
    • 它使用运行机制个S的像轻质够程参考值(可以有很多sudog S为相同够程),其允许快速跳跃到够程堆栈
    • 它使用调度程序的gopark机构阻止本身,其允许对信号高效出车
    • 时信号和已启动的,它会立即进入触发的情况下处理函数通过操纵select够程的程序计数器

没有单一的总体在实现突破性的想法,但你真的appre通过仔细修改每个步骤的方式,以便快速,高效并与渠道概念良好结合。因此,使用其他语言重新实现Go的select声明并不容易,除非您至少有第一个chan构造。

你可以看看其他语言的重新实现,其中的想法是重新与不同程度的相似性和有效性。如果我不得不在另一种语言中重新实现select,我可能会首先尝试一个共享信号量,如果没有工作,则切换到一个粗糙的程序,然后稍微休眠一下,订单策略。