3

私は最近、Googleのプログラミング言語であるGoについて学びました。私は、並行性のサポートが提供されていることに興味をそそられ、それについてさらに学ぶことに着手しました。しかし、私はGoが並行性の特定の機能をどのように実装しているかを見に行きました。これまでのところ、この機能がまったく存在しないという証拠はまったく見ていません。

これが架空の状況です。特定の入力のFoo値を決定する関数をプログラミングしていると仮定します。任意の入力について、Foo値はドメインAまたはドメインB(両方ではない)のいずれかにあります。これらのドメインでの検索の手法はまったく異なりますが、成功した検索はすぐに返される傾向があり、失敗した検索はデータセット全体を調べて網羅する必要があるため、時間がかかるという特性を共有しています。

さて、並行性を採用する他の言語(Cilkなど)では、関数Foosearchをプログラムして、Asearch関数とBsearch関数を生成することができます。これらの関数は同時に実行され、どちらかが答えを見つけたときはいつでも、その答えは呼び出し元の関数Foosearchに報告され、関数Foosearchは、生成された関数が返されなかった場合は終了します。

ただし、Goのゴルーチンでは、チャネルに接続できるルーチンは2つだけのようです。そのため、どちらが最初に回答を見つけたかに応じて、AsearchまたはBsearchのどちらかが送信できるチャネルを設定できず、Foosearchに読み取りを依頼できませんでした。それ。また、チャネルをブロックせずに読み取ることはできないようです。そのため、FoosearchでAsearchとBsearchを開始し、両方からチャネルを設定してから、ループで実行して、どちらかが生成されたかどうかを確認することはできませんでした。答え。

Goの並行性の限界についての私の理解は正しいですか?与えられた結果を達成する別の方法はありますか?

4

2 に答える 2

16

いいえ、Go の限界に関するあなたの理解は正しいとは思いません。

1 つには、チャネルを 2 つのルーチン間の通信に制限するものを Go で見たことがありません。同じチャネルを Asearch と Bsearch の両方に渡すことができ、どちらが終了してもそのチャネルで結果を送信できます。

代わりに 2 つのチャネルを使用し、そのうちの 1 つが結果を取得するのを待ちたい場合は、selectステートメントを使用できます。Go チュートリアルから、リクエストを送信するために使用されるチャネルを選択する例と、サーバーに終了するように通知するために使用されるチャネル:

21    func server(op binOp, service chan *request, quit chan bool) {
22        for {
23            select {
24            case req := <-service:
25                go run(op, req);  // don't wait for it
26            case <-quit:
27                return;
28            }
29        }
30    }

さらに、チャネルからの受信は通常ブロックされますが、チャネルからの非ブロック受信を行うこともできます。

フォームの代入または初期化で受信式が使用されている場合

x, ok = <-ch
x, ok := <-ch
var x, ok = <-ch

受信操作はノンブロッキングになります。操作を続行できる場合、ブール変数 ok が true に設定され、値が x に格納されます。それ以外の場合、ok は false に設定され、x はその型のゼロ値に設定されます (§ゼロ値)。

したがって、ブロックせずに複数のゴルーチンからの結果を待つ方法はいくつかあります。を使用して多重化された複数のチャネルを使用すると思いますselect。これにより、送信している値にその情報をパッケージ化したり、他の形式の帯域外通信を行ったりすることなく、どのルーチンが結果を返したかを簡単に知ることができます。

于 2009-11-15T18:10:30.377 に答える
5

キーワードを使用してselect、複数のチャネルから受信できます。

値は、他のチャネルよりも先に結果が得られたチャネルから取得されます。

var c1, c2 chan int;
var result int;

select {
case result = <-c1:
    print("received ", result, " from c1\n");
case result = <-c2:
    print("received ", result, " from c2\n");
}

参照

于 2009-11-15T18:10:03.187 に答える