標準出力への同時書き込みはスレッドセーフですか?
この質問は、標準出力 (stdout) ストリームへの同時書き込みのスレッド セーフに関するものです。行く。具体的には、次のコードを考えてみましょう。
<code class="go">package main import ( "fmt" "os" "strings" ) func main() { x := strings.Repeat(" ", 1024) go func() { for { fmt.Fprintf(os.Stdout, x+"aa\n") } }() go func() { for { fmt.Fprintf(os.Stdout, x+"bb\n") } }() go func() { for { fmt.Fprintf(os.Stdout, x+"cc\n") } }() go func() { for { fmt.Fprintf(os.Stdout, x+"dd\n") } }() <-make(chan bool) }</code>
明らかなデータ競合がないにもかかわらず、このコードのスレッド セーフについては議論があります。この問題を明確にするために、stdout への書き込みの仕組みを詳しく調べ、推奨事項とリファレンスを調べてみましょう。
FMT パッケージと IO.Writer
fmt パッケージの機能fmt.Fprintf など、io.Writer インターフェイスを実装する引数を受け入れます。これらは、このインターフェイスの Write メソッドを内部で呼び出します。
OS と stdout への同時アクセス
os.Stdout は、出力を次の宛先に送信する io.Writer インターフェイスの実装です。システムの標準出力。複数のゴルーチンが同時に os.Stdout に書き込む場合、この操作の実際のセマンティクスは基礎となるオペレーティング システムに委任されます。
POSIX システムの場合は、write(2) システム コールが使用されます。 POSIX では、通常のファイルとシンボリック リンクに対して、同時 write(2) 呼び出しがアトミックであると指定されています。ただし、この保証は他のファイル タイプや非 POSIX システムには適用されません。
Go 標準ライブラリとラッパー
Go 標準ライブラリは、書き込み用のラッパーを提供します。ファイル記述子とソケット。これらのラッパーは io.Writer インターフェイスを実装し、os.Stdout の場合、操作を関連するシステム コールにリダイレクトします。
Go ランタイムは、これらのラッパーが同時アクセスに対して内部的に安全であることを保証します。ただし、基礎となるオペレーティング システムに書き込みを中継するだけなので、同時実行のセマンティクスは最終的に OS によって決定されます。
標準出力同時書き込みの影響
推奨事項
参照
以上がGo での「stdout」への書き込みは本当にスレッドセーフですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。