2016-08-05 3 views
3

私はこのかなり基本的な問題の答えをオンラインで見つけられなかったので、何かを見逃しているに違いありません。私は3つのintの値を保持できるバッファードチャネルを使用しています。バッファリングされたチャンネルがいっぱいになるのを待つ

私はそれを埋めるために3つのゴルーチンを使用しています。バッファされたチャンネルがいっぱいになると操作をしたいと思います。ここで

は、問題を説明するスニペットです:

func main() { 
    // Initialization of the slice a and 0 < n < len(a) - 1. 
    difs := make(chan int, 3) 
    go routine(a[:n], difs) 
    go routine(a[n + 1:], difs) 
    go routine(a[n - 1:n + 1], difs) 

    fmt.Println(<-difs) // Display the first result returned by one of the routine. 
} 

func routine(a []int, out chan<- int) { 
    // Long computation. 
    out <- result 
} 

私はすべての値が計算されているときfmt.Println(<-difs)intの配列が表示されるように私のコードを更新したいと思います。私は3回使用することができます<-difsしかし、Goはそれを行うクリーナーを提供しているのだろうかと思います。

+0

多分あなたは[選択](https://tour.golang.org/concurrency/5) –

+3

を使用する必要があります[XY問題](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)のように、通常はチャンネルがいっぱいになるのを待つことはありません。 tはそれから同時に値を消費する。あなたはgoroutinesが完了するのを待っていますが、これはsync.WaitGroupを使用するものです。 – JimB

答えて

4

待ち:

package main 

import "fmt" 

func main() { 
    a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} // Initialization of the slice a and 0 < n < len(a) - 1. 
    difs := make(chan int, 3) 

    go routine(a[0:4], difs) 
    go routine(a[4:8], difs) 
    go routine(a[8:12], difs) 

    result := []int{<-difs, <-difs, <-difs} 

    fmt.Println(result) // Display the first result returned by one of the routine. 
} 

func routine(a []int, out chan<- int) { 
    result := 0 // Long computation. 
    for _, v := range a { 
     result += v 
    } 
    out <- result 
} 

出力:

[10 42 26] 
+0

シンプルで効果的です、ありがとうございます!私は 'sync.WaitGroup'を使用するので、他の答えをアップアップします。これは、この種の問題の標準的な解決策です。 –

+0

@ armand-grillet sync.WaitGroupは必要ありません。ちょうど3チャンネルですが、チャンネル自体を使って同期することができます。 –

+0

メッセージ数が可変である場合は、新しいゴルーチンを起動して完了したときに追加または削除できるため、待機グループは特に適しています。 – Kaedys

4

機能len()はチャネルをサポートし、チャネル内の未読のキューに入れられた要素の数を返します。ただし、ループを定期的にチェックする必要があります。

このように、sync.WaitGroupを使用して処理する従来の方法:この作業サンプルコードのように、チャネル自体を用い

func main() { 
    // Initialization of the slice a and 0 < n < len(a) - 1. 
    var wg sync.WaitGroup 
    wg.Add(3) 
    difs := make(chan int, 3) 
    go routine(a[:n], difs, &wg) 
    go routine(a[n + 1:], difs, &wg) 
    go routine(n - 1:n + 1], difs, &wg) 

    wg.Wait() // blocks until wg.Done() is called 3 times 
    fmt.Println(<-difs) // Display the first result returned by one of the routine. 
} 

// NOTE: This MUST accept a POINTER to the waitgroup. They are not copy-safe. 
func routine(a []int, out chan<- int, wg *sync.WaitGroup) { 
    defer wg.Done() 
    // Long computation. 
    out <- result 
} 
関連する問題