それはゴーでゴルーチンのうちの1つから結果を受信することは可能ですか?
-
20-09-2019 - |
質問
私はつい最近、Googleのプログラミング言語、ゴーについて学びました。私は、同時実行のためにその提供するサポートに興味をそそられ、それについての詳細を学ぶために着手してきました。しかし、私は行くが、同時実行の特定の機能を実装し、これまでのところ、私はすべてでこの機能がすべてであることを証拠を見ていないかを確認するために探して行きました。
私たちは、特定の入力のFooの値を決定するための機能をプログラミングしているとします。ここでは仮定の状況があります。任意の所与の入力のために、Fooの値は、いずれかのドメインA、またはドメインB(両方ではないで)に見出されます。これらのドメインでの検索の技術はかなり異なっているが、彼らは成功した検索が失敗した検索は、網羅的であること、したがって、長い時間がかかるために、データセット全体を通過する必要がありながら、すぐに戻る傾向があるという性質を共有します。
次に、並行処理を用いる他の言語の一つはプログラム可能性(例えば、のCilk のような)関数FoosearchそれはAsearch機能とBSEARCH機能を生み出したことになります。これらの機能は、同時に実行されます、そして、のいずれかのそれらの答えを思い付いた時はいつでも、その答えが返されていなかった、それが生み出されていたすべての機能を終了させる呼び出し関数Foosearchに報告されます。
あなたはAsearchかBSEARCHどちらかが最初の答えを見つけたかに応じて、送信することができているチャンネルを設定することができませんでした、と持っている - あなたが唯一のチャネルで2つのルーチンを接続することができますようには、ゴーのゴルーチンでは、しかし、それが見えますFoosearchはそれから読み取ります。どちらか一方が生産しているかどうかをチェックするループ内で実行しますので、あなたはFoosearchがAsearchとBSEARCHを開始し、両方のチャンネルを設定していることができませんでした - あなたはそれをブロックすることなく、チャネルから読み取ることができないようにまた見えます答えます。
ゴーの並行処理の制限の私の理解は正しいですか?指定された結果を達成するための別の方法はありますか?
解決
いいえ、私が行くの限界についての理解が正しいとは思わない。
一つには、私は2つのルーチン間の通信にチャンネルを制限ゴーで見てきた何もありません。あなたがAsearchとBSEARCHの両方に同じチャネルを渡すことができ、その後、いずれか1つの仕上げは、そのチャネル上で結果を送信することができます。
の代わりに使用すると、2つのチャネルを使用していた、との結果を得るためにそれらの1を待つ場合は、あなただけの<のhref =「http://golang.org/doc/go_spec.html#Select_statements」のrelを使用することができます= "nofollowをnoreferrer"> select
の声明。 はチュートリアルに、要求を送信するために使用されるチャネル上で選択する例、およびに使用したものを行きます終了するには、サーバーを合図ます:
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がします進めます 真とに格納された値に設定します バツ;そうでない場合は、[OK]を偽とXに設定されています その型のゼロ値に設定されています (ゼロ値を§)。
だから、ブロックすることなく、複数のゴルーチンからの結果を待つには、いくつかの方法があります。私はその方法として、あなたが簡単にあなたがアウト・オブ・バンド通信のいくつかの他のフォームを送信したり、やっている値に、その情報をパッケージ化しなくても結果を返されたルーチン伝えることができ、select
を使用して多重化、複数のチャネルで行くと思いますます。
他のヒント
あなたは、複数のチャネルから受信する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");
}