ホームページ  >  記事  >  バックエンド開発  >  goroutine を使用して値を処理し、結果をスライスに収集するときにデッドロックを回避するにはどうすればよいですか?

goroutine を使用して値を処理し、結果をスライスに収集するときにデッドロックを回避するにはどうすればよいですか?

DDD
DDDオリジナル
2024-11-06 17:56:02969ブラウズ

How to Avoid Deadlock When Using Goroutines to Process Values and Gather Results into a Slice?

ゴルーチンを使用して値を効率的に処理し、結果をスライスに収集する

ゴルーチンの利用は Go プログラミングの変革的な要素となり、タスクの同時実行と効率的な処理。ただし、潜在的な落とし穴を回避するには、適切な実装が重要です。

問題:

コードベースでゴルーチンを使用しようとすると、「致命的なエラー: すべてのゴルーチンがスリープ状態です -行き詰まり!」が生じます。目的は、リスト内の値を同時に処理し、その後、処理された結果を新しいリストに蓄積することです。ただし、蓄積フェーズでは困難が生じます。

コード分解:

提供されたコード スニペットには、いくつかの重要な要素が含まれています:

// Process each item with a goroutine and send output to sampleChan
go newSample(line, *replicatePtr, *timePtr, sampleChan, &wg)
  • このゴルーチンはデータを同時に処理し、その結果をsampleChanという名前のチャネルに送信します。
// Read from sampleChan and put into a slice
for s := range sampleChan {
    sampleList = append(sampleList, s)
}
close(sampleChan)
  • コードはチャネルから結果を収集し、それらをスライスに組み込もうとします。

解決策:

エラーは、ワーカーの完了を待機する時期が早すぎることと、チャネルを閉じるタイミングが不適切であるという 2 つの問題によって発生します。次の変更により、これらの問題が解決されます。

go func() {
    wg.Wait()
    close(sampleChan)
}()
  • 別の goroutine を開始してワーカーが終了するまでチャネルの閉鎖を延期します。

さらに、スタイルの一貫性を保つために、再構築を検討してください。 newSample を結果生成用の同期関数として使用すると、次のコードが生成されます。

for i, line := range contents {
    wg.Add(1)
    go func(line string) {
        defer wg.Done()
        sampleChan <- newSample(line, *replicatePtr, *timePtr)
    }(line)
}

この改訂されたアプローチにより、コードの可読性が向上し、テストが容易になり、同時実行管理が簡素化され、wg.Done( などの重要な操作を明確に識別できるようになります。 ).

以上がgoroutine を使用して値を処理し、結果をスライスに収集するときにデッドロックを回避するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。