ホームページ > バックエンド開発 > Golang > 並列処理と結果収集にゴルーチンを使用するときにデッドロックを回避するにはどうすればよいですか?

並列処理と結果収集にゴルーチンを使用するときにデッドロックを回避するにはどうすればよいですか?

Barbara Streisand
リリース: 2024-11-07 02:09:03
オリジナル
580 人が閲覧しました

How to Avoid Deadlocks When Using Goroutines for Parallel Processing and Result Gathering?

並列処理と結果収集のためのゴルーチンを理解する

背景

あなたの目標は、Go でゴルーチンを利用してアイテムを並列処理し、その結果を収集することです。スライスに。ただし、複雑なデッドロック エラーが発生しました: 「すべてのゴルーチンがスリープ状態です - デッドロック!」

解決策

このエラーは、コード内の 2 つの問題に起因します:

  1. 遅延収集: 結果を収集する前にすべてのゴルーチンが完了するのを待っていますが、これは正しくありません。
  2. 早期チャネル閉鎖: チャネルは結果収集後に閉じられます。ループが終了し、反復が途中で終了します。

改訂されたコード

これらの問題を修正するには、ワーカーの終了時にチャネルを非同期で閉じるゴルーチンを導入します。

for i, line := range contents {
  wg.Add(1)
  go newSample(line, *replicatePtr, *timePtr, sampleChan, &wg)
}

go func() {
  wg.Wait()
  close(sampleChan)
}()

for s := range sampleChan {
  ..
}
ログイン後にコピー

説明

  • 非同期チャネルの終了: 匿名ゴルーチンは、すべてのワーカーが完了した後にチャネルを閉じ、早期のループ終了を回避します。
  • スタイルの推奨事項: チャネルと待機グループを使用しない同期ヘルパー関数 (newSample) の使用を検討して、コードを簡素化し、テスト容易性を高めます。

効率化のためのリファクタリング

最適な効率を得るために固定数のワーカーが必要な場合は、次のようにコードをリファクタリングします。

for i, line := range contents {
  wg.Add(1)
  go func(line string) {
    defer wg.Done()
    sampleChan <- newSample(line, *replicatePtr, *timePtr)
  }(line)
}
ログイン後にコピー

これにより、同時実行プリミティブがまとめられ、さまざまな同時実行パターンのリファクタリングが簡素化されます。

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

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート