2
私は次のコードを持っている:それはライン18上のデッドロックになり複数のGoroutinesを閉じることができますか?
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
stuff := fanIn(
generator(4, 5, 6, 7),
generator(1, 2, 6, 3, 7),
generator(12, 15, 33, 40, 10),
generator(18, 13, 20, 40, 15),
generator(100, 200, 64000, 3121, 1237),
)
for v := range stuff {
fmt.Println(v)
}
fmt.Println(t.Sub(time.Now()))
}
func generator(nums ...int) <-chan int {
out := make(chan int, 10)
go func() {
defer close(out)
for _, v := range nums {
out <- v
}
}()
return out
}
func fanIn(in ...<-chan int) <-chan int {
out := make(chan int, 10)
for _, v := range in {
go func(ch <-chan int) {
for val := range ch {
go func(c int) { out <- c }(val)
}
}(v)
}
return out
}
を:(と思う)
for v := range stuff {...}
問題は、私はファンイン機能に密接に延期ていないよということです読み取り専用チャンネルを返します。複数のゴルーチンの終了を待つ必要があるので、いつ延期するのか分かりません。
このデッドロックを解決するための慣習的な方法は何ですか?このコードは慣用句ですか?
ありがとうございます!
素晴らしい。私はsync.WGが必要だと思ったが、別のゴルーチンでそれを使うとは思わなかった。とても簡単です。ありがとう! –
ちょっと分かりました。ちょっとだけプリミティブを使う方法はありませんか? fanIn(またはmerge)funcのout-chanを閉じるにはWaitGroupが必要ですか? –
事前に操作の数、たとえば一定数のゴルーチンからチャンネルに到着したメッセージの数などが分かっている場合は、チャンネルのみを使用して同期する方がよい場合があります。例のために、設定された回数だけチャネル上の 'for'ループ(' range'ではなく)です。 – abhink