Go での並列処理
並列プログラミングには、複数のタスクを同時に実行することが含まれ、独立したユニットに分割できるアプリケーションのパフォーマンスを向上させることができます。 Go で並列処理を実現する 1 つの方法は、メイン プログラムと同時に実行される軽量スレッドであるゴルーチンを使用することです。
次のコードを考えてみましょう。
<code class="go">package main import ( "fmt" "math/rand" "time" ) func main() { for i := 0; i < 3; i++ { go f(i) } // prevent main from exiting immediately var input string fmt.Scanln(&input) } func f(n int) { for i := 0; i < 10; i++ { dowork(n, i) amt := time.Duration(rand.Intn(250)) time.Sleep(time.Millisecond * amt) } } func dowork(goroutine, loopindex int) { // simulate work time.Sleep(time.Second * time.Duration(5)) fmt.Printf("gr[%d]: i=%d\n", goroutine, loopindex) }</code>
このコードは、ゴルーチンを使用して f を同時に実行します。 3回機能します。 dowork 関数は、5 秒間スリープすることで一部の作業をシミュレートします。
dowork 関数が並列実行されると想定できますか?
はい、この想定は可能です。デフォルトでは、Go は GOMAXPROCS を使用可能なコアの数に設定します。これにより、複数のゴルーチンを同時に実行できます。
これは並列処理を実現する正しい方法ですか?
です。並列処理を実現する有効な方法ですが、最も効率的なアプローチではない可能性があります。同期メカニズムなしでゴルーチンを使用すると、データ競合や不正確な結果が発生する可能性があります。
チャネルと個別の dowork ワーカーの使用
並列処理を実現するためのより構造化されたスケーラブルな方法は、次のとおりです。チャネルと個別の Dowork ワーカー。このアプローチにより、各ゴルーチンが共有データの独自のコピーを持ち、メッセージ パッシングを通じて通信することが保証されます。
チャネルを使用した例を次に示します。
<code class="go">var results = make(chan int) // channel to collect results func main() { // spawn a worker for each goroutine for i := 0; i < 3; i++ { go worker(i) } // collect results from the worker goroutines for i := 0; i < 10; i++ { result := <-results fmt.Println("Received result:", result) } } func worker(n int) { for i := 0; i < 10; i++ { // perform work and send result through the channel res := dowork(n, i) results <- res } }</code>
結論
Go の並列処理はゴルーチンを使用して実現できます。チャネルと個別のワーカーを使用することは、データの整合性を確保し、パフォーマンスを向上させる、より構造化されたスケーラブルなアプローチです。
以上がgoroutine を単独で使用する場合と比較して、チャネルと個別のワーカーを使用すると Go の並列処理をどのように改善できるでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。