2016-05-04 6 views
4

特に、私はC++でいくつかのブロッキングキューを持っています。それらのいずれかに私がポップできるアイテムがあるまで待ちたいと思います。golangのselect文はどのように実装されていますか?

私が考えることができる唯一のメカニズムは、入力キューからポップし、元のスレッドが待機できるマスターキューにフィードする各キューに対して別個のスレッドを生成することです。

N個の新しいスレッドを生成し、キューのグループからポップするたびにそれらをすべて終了させるのは、リソースが重いようです。

Golangは私自身のC++コードで実装できるより洗練されたメカニズムを実装していますか?

+0

標準的な機能だけを使って、1つのスレッドで複数の条件変数を待つことはできません。たぶんあなたは問題を逆転させて、キューを積極的に "マスター"キューにプッシュして、ブロッキングスレッドに通知します。 – melak47

+1

Goの選択実装は[ここ](https:// github。com/golang/go/blob/master/src/runtime/select.go)、おそらくそれはあなたにアイデアを与えることができます。 –

+0

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

答えて

-1

Golangのselect文がC select機能(documentation libcのGNUを参照)からインスピレーションを得ている、それはファイルディスクリプタのセットにI/Oを待っているために使用されます。キューがソケットまたはパイプを使用して通信する場合は、それを使用できます。

4

Goのselect実装はエレガントだとは必ずしも言えませんが、それは独自の方法で美しく、かなり最適化されていると思います。

  • それ単一の非デフォルトのケースで特殊ハンドルselect
  • それは例が、それは見ている例を超える楽観最初のパスを行い、確定飢餓
  • を避けるために評価される順序を並べ替えますすでに
  • 満足だいずれかにそれがを使用する唯一のランタイムメカニズム
    • に知られている、内部の多くを使用して、各チャンネルの内部送信者/受信キューにエンキュー軽量ゴルーチン参照のようなものですsがゴルーチンスタックに素早くジャンプできるよう(同じゴルーチンのための多くのsudogの存在することができます)、それは、信号の効率的なunparkingすることができます自分自身をブロックするスケジューラのgoparkメカニズムを使用しています
    • 合図とパーク解除、それはすぐそこ実装でアイデアを画期的単一の包括的なはませんが、あなたは本当にappreだろう

selectゴルーチンのプログラムカウンタを操作することにより、トリガーケースハンドラ関数に入ります各ステップがどのように慎重に操作されているかを確認し、迅速で効率的で、チャネルの概念とうまく統合できるようにします。そのため、あなたが少なくともchan構造を最初に持っていない限り、Goのselectステートメントを別の言語で再実装することはあまり簡単ではありません。

他の言語でも利用可能な再実装を見てみましょう。アイデアはさまざまな類似性と有効性で再現されました。 selectを別の言語で最初から再実装しなければならない場合は、最初に単一の共有セマフォを試してみて、それがうまくいかなかった場合には、より穏やかなsleep-注文戦略。

関連する問題