2009-11-13 4 views
8

私が今まで見たすべての例は、結果を得るためにブロックすることを含んでいます(<-chan演算子経由)。ブロックせずにゴルーチンが完了しているかどうかを確認するにはどうすればよいですか?

私の現在のアプローチは、構造体へのポインタを渡す必要:ゴルーチンが完了した時点で書き込み

type goresult struct { 
    result resultType; 
    finished bool; 
} 

。都合の良いときにはいつでもfinishedをチェックするのは簡単なことです。より良い選択肢がありますか?

私が本当に目指しているのは、Qtスタイルの信号スロットシステムです。私は解決策がほとんど些細な(chanのは、潜在的なの)がありますが、私はそれを把握する言語ではまだ十分に精通していない見た目を持っています。

答えて

13

あなたは「カンマ、OK」パターン(「effective go」に自分のページを参照)を使用することができます:あなたはまた、それがlenを使って、何が含まれているかどうかを確認するためにチャネルバッファを覗くことができます

foo  := <- ch; // This blocks. 
foo, ok := <- ch; // This returns immediately. 
+1

これはもう有効ではありません。 – rog

+1

あなたは次のように書く必要があります。 { case foo:= <-ch: default: } – rog

4

Select statementsあなたは(通信が待機しているものの)ランダムな枝を取って、一度に複数のチャンネルを確認することができます:すべての送信のために

func main() { 
    for { 
    select { 
     case w := <- workchan: 
      go do_work(w) 
     case <- signalchan: 
      return 
     // default works here if no communication is available 
     default: 
      // do idle work 
    } 
    } 
} 

と「選択」で 表現を受け取りますステートメント のチャネル式が評価され、 の右側に表示される式は、 の式を上から下に順番に送信します。 結果の操作のいずれかが実行できる場合、 が選択され、対応する通信と ステートメントが評価されます。それ以外の場合、 デフォルトのケースがある場合は、 が実行されます。そうでない場合は、通信の1つが が完了するまで、文はブロック をブロックします。

+0

@ジュリーリー:それについては確かですか?それは正しいはずですが、 '< - の後ろに空白がなければ、より良く見えます。 – u0b34a0f6ae

+0

+1; Goコードを公開するときは常にgofmtを使用してください。 – rog

3

を:

if len(channel) > 0 { 
    // has data to receive 
} 

これは値gotValue == true除去するfoo, gotValue := <- chとは異なり、チャネル・バッファには触れません。

関連する問題