Go: デッドロック パニック - 原因の理解と修正
Go で発生する一般的なエラーは、「致命的なエラー: すべてのゴルーチンが眠っている - デッドロック!」 goroutine 間の通信を管理しようとするとき。このエラーは、ゴルーチンが互いに続行を待機している状態でスタックした場合に発生します。
問題ステートメント
読み取り対象となる次のコードを考えてみましょう。テキスト ファイルから単語の行を抽出し、チャネルに保存して、個別に出力します。
func main() { f, _ := os.Open("D:\input1.txt") scanner := bufio.NewScanner(f) file1chan := make(chan string) for scanner.Scan() { line := scanner.Text() parts := strings.Fields(line) for i := range parts { file1chan <- parts[i] } } print(file1chan) } func print(in <-chan string) { for str := range in { fmt.Printf("%s\n", str) } }
デッドロックの原因
このコードを実行すると、デッドロック エラーが発生します。これは、チャネル file1chan がバッファリングされていないために発生します。その結果、チャネルに値を送信しようとすると、チャネルは無限にブロックされ、受信者を待ちます。
デッドロックの修正
デッドロックを解決するには、 2 つのオプションがあります:
バッファリングされたチャネルを使用する:
make(chan) の 2 番目の引数としてサイズを指定することで、バッファリングされたチャネルを作成できます。
file1chan := make(chan string, 1) // buffer size of one
バッファリングされたチャネルは配列のように機能し、チャネルに利用可能な容量がある場合、送信者はブロックせずに値を送信できます。
新しいゴルーチンを使用する:
バッファされていないチャネルに値を送信するために新しいゴルーチンを開始できます:
file1chan := make(chan string) go func() { // start a new goroutine that sends strings down file1chan for scanner.Scan() { line := scanner.Text() parts := strings.Fields(line) for i := range parts { file1chan <- parts[i] } } close(file1chan) }() print(file1chan)
このアプローチでは、新しいゴルーチンが値を送信する責任を負います。メインのゴルーチンはそれらを出力することに重点を置いています。
これらのソリューションのいずれかを実装すると、デッドロックが効果的に排除され、ゴルーチン間のスムーズな通信が可能になります。
以上がGo プログラムで「致命的エラー: すべてのゴルーチンがスリープ中 - デッドロック!」が発生するのはなぜですか?また、それはどのように修正できるのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。