Go でファイル書き込みブロックが発生すると最小限のスレッド作成が発生する理由
Go では、ゴルーチンが呼び出しをブロックすると、通常、スレッドが作成されます。そのような操作を容易にします。ただし、ファイルに書き込もうとしているときに複数のゴルーチンがブロックされると、不可解な観察が発生します。多数のゴルーチンが存在するにもかかわらず、確立されるスレッドの数は限られています。
テスト コードと観察
次のテスト スクリプトは、この動作を示しています。
package main import ( "io/ioutil" "os" "runtime" "strconv" ) func main() { runtime.GOMAXPROCS(2) data, err := ioutil.ReadFile("./55555.log") if err != nil { println(err) return } for i := 0; i < 200; i++ { go func(n int) { for { err := ioutil.WriteFile("testxxx"+strconv.Itoa(n), []byte(data), os.ModePerm) if err != nil { println(err) break } } }(i) } select {} }
皮肉なことに、このスクリプトが実行されると、少数のスレッドのみが作成されます。コマンド:
$ cat /proc/9616/status | grep -i thread Threads: 5
難問の解決
この動作を理解する鍵は、ブロック操作の性質にあります。元のテストでは、ファイルの書き込みがあまりにも早く完了して新しいスレッドの作成をトリガーできませんでした。
これを説明するために、より大きなデータ ブロックを書き込むようにテスト スクリプトが変更されました。
package main import ( "io/ioutil" "os" "runtime" "strconv" ) func main() { runtime.GOMAXPROCS(2) data := make([]byte, 128*1024*1024) for i := 0; i < 200; i++ { go func(n int) { for { err := ioutil.WriteFile("testxxx"+strconv.Itoa(n), []byte(data), os.ModePerm) if err != nil { println(err) break } } }(i) } select {} }
この変更により、次のように 200 を超えるスレッドが作成されました。 command:
$ cat /proc/17033/status | grep -i thread Threads: 203
結論
したがって、ファイル書き込み操作が迅速に実行される場合、呼び出しのブロック性は複数のファイルの作成をトリガーするのに十分ではない可能性があります。スレッド。ブロック操作がより実質的になる場合にのみ、追加のスレッドの必要性が明らかになり、予想どおりスレッドが急増します。
以上が多くのゴルーチンが高速ファイル書き込みをブロックするのに、Go がほとんどスレッドを作成しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。