Goクロージャが参照によって外部変数をキャプチャすることを観察して確認しました。変数がゴルーチンにキャプチャされ、ゴルーチンが別のスレッドに多重化されている場合、
- クロージャの値を変更しても安全ですか?
- 安全ではない場合、なぜGoはこれを防がないのでしょうか?
- それとも何らかの安全機構を採用していますか?(ロックなど)
Goクロージャが参照によって外部変数をキャプチャすることを観察して確認しました。変数がゴルーチンにキャプチャされ、ゴルーチンが別のスレッドに多重化されている場合、
お気づきのように、Go はクロージャー内の参照によって外部変数をキャプチャします。
クロージャの値を変更しても安全ですか?
これは他の変数と同様に変数であるため、通常の Go コードと同じルールが適用されます。変更しても安全ですが、同時に変更する場合は、独自のロックを提供するか、アトミック タイプを使用する必要があります。
詳細については、Go メモリ モデルを参照してください。
安全でない場合は、Go でこれを防いでみませんか?
これは、go ルーチン間で共有される他の変数へのアクセスと同じです。あなたは安全にそれを行うことができ、あなたはそれを危険にさらすことができます-Goは、必要に応じて自分の足を撃つ自由を与えます.
Go には優れた競合検出機能がありますが、変数への同時アクセスの問題を見つけることができます。
それとも、何らかの安全装置を採用していますか? (ロックなど)
いいえ。Go がロックすることはありません。同期パッケージで提供されているプリミティブを使用するか、メモリを共有して通信しないという Go の哲学に従う必要があります。代わりに、通信によってメモリを共有します。つまり、チャネルを使用して go ルーチン間で話します。