ホームページ  >  記事  >  バックエンド開発  >  Go でゴルーチンから結果を収集するときにデッドロックを回避するにはどうすればよいですか?

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

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-11-07 12:56:03673ブラウズ

How to Avoid Deadlocks When Gathering Results from Goroutines in Go?

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

ゴルーチンは、同時プログラミングのための Go の基本的な概念です。メインスレッドをブロックすることなく、複数のタスクを同時に実行できます。ただし、ゴルーチンの使用は、特に複数のゴルーチンから結果を収集する場合に注意が必要です。

問題ステートメント

開発者は、ゴルーチンを使用して次のゴルーチンのリストを処理しようとしました。項目を作成し、処理された値をスライスに収集します。しかし、彼らは恐ろしい「すべてのゴルーチンが眠っている - デッドロック!」に遭遇しました。 error.

デッドロックの根本原因

コードが結果を収集する前にすべての goroutine の処理が完了するのを待っていたため、デッドロックが発生しました。これにより、ゴルーチンがスライスへの書き込みが可能になるのを待機している一方で、メインスレッドはゴルーチンの処理が完了するのを待機しているという状況が発生しました。

解決策

デッドロックを解決するには、ゴルーチンとメインスレッド間の通信に使用されるチャネルの非同期クローズを導入する必要があります。以下の変更されたコードは、解決策を示しています。

// ...

// Create a channel to receive the processed values
sampleChan := make(chan sample)

var wg sync.WaitGroup

// Process each item in the list with a goroutine
for i, line := range contents {
    wg.Add(1)
    go func(line string) {
        defer wg.Done()
        // Process the item and send the result on the channel
        sampleChan <- newSample(line, *replicatePtr, *timePtr)
    }(line)
}

// Asyncronously close the channel when all goroutines are done
go func() {
    wg.Wait()
    close(sampleChan)
}()

// Read from the channel and gather results into a slice
var sampleList []sample
for s := range sampleChan {
    sampleList = append(sampleList, s)
}

// ...

チャネルを非同期で閉じることにより、ゴルーチンの処理中であっても、メインスレッドは結果の収集を続行できます。これにより、デッドロックが解消され、コードが正しく実行できるようになります。

追加の考慮事項

この解決策はデッドロックを解決しますが、完全な解決策ではないことに注意してください。この特定のシナリオで同時実行を管理するためのものです。要件とゴルーチンの数に応じて、コードの信頼性と正確性を確保するために追加の同期およびエラー処理メカニズムが必要になる場合があります。

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

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