同時マップ変更の処理: リカバリと実行時クラッシュのジレンマ
同時マップ アクセスを扱う場合、次のような特殊な状況に遭遇する可能性があります。 「同時マップ読み取りとマップ書き込み」パニックから回復することは無駄に思えます。これは、そのような場合のランタイムの動作はパニックではなく、意図的なクラッシュであるためです。
Go 1.6 では、ランタイムにマップの同時誤用の検出メカニズムが導入されました。複数のゴルーチンが同時にマップを変更しようとすると、ランタイムがクラッシュを引き起こし、診断メッセージを出力します。この動作は、マップが書き込み操作のために同時にアクセスされる場合に、未定義の動作が発生する可能性があるという本質的な危険性から生じています。
残念ながら、パニックを処理するために defer と Recovery を使用する一般的なアプローチは、このシナリオでは効果がありません。リカバリ関数は、ランタイムによって開始されたクラッシュをインターセプトできません。推奨される解決策は、マップの同時誤用を完全に防ぐことです。
提供された例では:
package main import "time" var m = make(map[string]string) func main() { go func() { for { m["x"] = "foo" } }() go func() { for { m["x"] = "foo" } }() time.Sleep(1 * time.Second) }
マップ "m" への同時書き込みにより、ランタイム クラッシュがトリガーされます。これを防ぐには、書き込み操作中にマップへの排他的アクセスを保証するために、ミューテックスやチャネルの使用などの同期メカニズムを採用する必要があります。
以上がGo での同時マップ変更クラッシュの処理に「recover」が失敗するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。