値による構造の受け渡しによる Go チャネル通信のデッドロック
コード内で、ゴルーチン チャネルでデッドロック エラーが発生しましたコミュニケーション。このエラーは、WaitGroup 構造体を値によってゴルーチンに渡しているため、元の参照を共有する代わりに WaitGroup のコピーが作成されることが原因です。
値による受け渡しがデッドロックを引き起こす理由
Go の構造体は、参照ではなく値によって渡されます。構造体を関数に渡すと、コピーが作成されて関数に渡されます。これは、関数内の構造に加えられた変更は、関数の外側の元の構造には反映されないことを意味します。
あなたの場合、ゴルーチンはタスクの完了時に WaitGroup に信号を送ろうとしています。ただし、WaitGroup のコピーを使用しているため、Done() 呼び出しは元の WaitGroup には影響しません。その結果、メインの goroutine の Wait() 呼び出しが完了せず、デッドロックが発生します。
解決策: ポインターによる受け渡し
この問題を解決するには、次のようにします。 WaitGroup をポインタによってゴルーチンに渡す必要があります。これにより、ゴルーチンとメインのゴルーチンの両方が WaitGroup への同じ参照を共有するようになります。
作業例:
コードの修正バージョンは次のとおりです:
<code class="go">package main import ( "fmt" "sync" ) func push(c chan int, wg *sync.WaitGroup) { for i := 0; i < 5; i++ { c <- i } wg.Done() } func pull(c chan int, wg *sync.WaitGroup) { for i := 0; i < 5; i++ { result, ok := <-c fmt.Println(result, ok) } wg.Done() } func main() { var wg sync.WaitGroup wg.Add(2) c := make(chan int) go push(c, &wg) go pull(c, &wg) wg.Wait() }</code>
これで、このコードを実行すると、デッドロック エラーが発生しなくなります。 goroutine は WaitGroup に正常に信号を送り、メインの goroutine はその実行を完了できるようになります。
以上がWaitGroup 構造体を値で渡すと Go チャネル通信でデッドロックが発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。