2017-12-04 9 views
0

新しいlangに移動すると私はgoroutinesを使用する単純な再帰アルゴリズムを作成しようとしています。私はgoroutineからの出力を受け取るためにチャンネルを使用していますが、そうしようとすると「致命的なエラーが発生します:すべてのgoroutinesが眠っています - デッドロックです!エラー。私がチャンネルコードをコメントアウトすると、すべてうまく動作します。 これは私のコードですチャンネルを使用しているときにゴルーチンデッドロック

package main 

import (
    "fmt" 
    "sync" 
) 

func main() { 
    numbers := []int{2, -1, 10, 4, 3, 6, 22} 

    ch := make(chan []int) 

    wg := &sync.WaitGroup{} 
    wg.Add(1) 
    go testFunc(numbers, ch, wg) 
    wg.Wait() 

    result := <-ch 

    fmt.Println("Result: ", result) 
} 

func testFunc(numbers []int, ch chan []int, wg *sync.WaitGroup) { 
    defer wg.Done() 
    ch <- numbers 
} 

私は間違っていますか?私はgoroutineのチャンネルに値を割り当ててメインでそれを読んでいます。コミュニケーションするのに十分ではありませんか?

+0

チャンネルから受信する前に、ゴルーチンを待っています。ここにはバッファされていないチャンネルがあるので、待機グループは必要ありませんし、ゴルーチンもまったく必要ありません。 – JimB

答えて

4

バッファなしチャネルでの通信chは、送信側と受信側の両方が準備ができている場合にのみ成功します。

main関数は、値を受け取る前に待機グループで待機します。ゴルーチンは、コールwg.Doneの前にチャンネルを送信しようとします。それはデッドロックです。

 ch := make(chan []int, 1) 

別の修正がwg.Waitを呼び出す前に、チャネル上で受信することです():

一つの修正はバッファリングされたチャネルを使用することです。

result := <-ch 
wg.Wait() 

さらに別の修正は、待機グループを使用してすべての行を削除することです。この具体的な例では不要です。

+0

バッファリングチャネルが私の問題を解決しました。現在のコードをどのように変更し、バッファされたチャンネルを使用しないのですか? – Lukenzo

+0

もう1つの修正点は、wg.Wait()を呼び出す前にチャネルで受信することです。 –

+0

少なくとも(この例では)待機グループは必要ありません。関数が送信するまで(バッファされていない)チャンネルで受信することはできません。これは返される前の最後のものです。 – Adrian

関連する問題