問題は Go コンパイラーによる最適化ではなく、同期の欠如です。 i への代入の後には同期イベントが続かないため、他のゴルーチンによって監視されることは保証されません。実際、積極的なコンパイラは i ステートメント全体を削除する可能性があります。
Go メモリ モデル
Go メモリ モデルは、変数を 1 つのステートメントで読み取る条件を指定します。 goroutine は、別の goroutine 内の同じ変数への書き込みによって生成された値を監視することを保証できます。
アクセスをシリアル化するには、チャネル操作または他の同期プリミティブ (sync パッケージや sync/atomic パッケージにあるものなど) を使用してデータを保護します。 .
プログラムの動作を理解するためにこのドキュメントの残りの部分を読まなければならないとしたら、あなたは賢すぎます。
同期
次の例では、 a への代入の後に同期イベントが続かないため、監視されるかどうかは保証されません。他のゴルーチンによって。実際、積極的なコンパイラは go ステートメント全体を削除する可能性があります。
<code class="go">var a string func hello() { go func() { a = "hello" }() print(a) }</code>
次の例は、sync.Mutex.
<code class="go">package main import ( "sync" "time" ) func main() { mx := new(sync.Mutex) i := 1 go func() { for { mx.Lock() i++ mx.Unlock() } }() <-time.After(1 * time.Second) mx.Lock() println(i) mx.Unlock() }</code>
以上が私のゴルーチンの値が他の人に表示されないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。