はじめに
2つ目の記事のテーマはgoroutineを使用した並行処理です。
Goの強みとして並行処理が得意なことは知っているけど、具体的な使い方がわからない、そもそも並行処理がどのようなものかもわからないという方向けの並行処理基礎講座です。ぜひ見ていってください。
並行処理とは
そもそも並行処理とは、コンピュータプログラムが同時に複数のタスクを実行できるようにする計算概念のことです。一般的なプログラミングモデルでは、処理は1つ1つ順番に実行されます。つまり、Aというタスクを実行した場合、途中でやめるか終了するまでBという次のタスクに移ることはできません。しかし、並行処理では、複数のタスクが同時に進行でき、各タスクの実行がお互いに干渉することも可能となります。
並列処理との違い
並行処理はよく、並列処理と間違われることがあります。その実、並行処理と並列処理は、両方とも複数のタスクが同時に進行することを意味します。しかし、微妙な違いがあるのです。 簡潔に言えば、並行処理は複数のタスクが同時に進行しているように見えるが、実際には同時には実行されていない場合があります。一方、並列処理では、複数のタスクが同時に実際に実行されるという違いがあります。もっと詳しい違いを知りたい方は、こちらをご覧ください。とても分かりやすく説明されています。
実際に使ってみた
Go言語で並行処理を使った簡単なコードを書いてみました。
この例では、goroutineを使用して、異なる処理を並行して実行しています。
package main
import (
"fmt"
"sync"
"time"
)
func main() {
// WaitGroupを作成して、goroutineの終了を待つ
var wg sync.WaitGroup
// 並行して実行する処理の数
numProcesses := 5
// ゴルーチンの数だけカウントを増やす
wg.Add(numProcesses)
// 並行処理を開始
for i := 0; i < numProcesses; i++ {
go func(id int) {
// 処理の完了をWaitGroupに通知
defer wg.Done()
// 何らかの処理を行う
fmt.Printf("処理 %d 開始\n", id)
time.Sleep(time.Second) // 例として1秒スリープ
fmt.Printf("処理 %d 完了\n", id)
}(i)
}
// すべてのgoroutineが終了するのを待つ
wg.Wait()
fmt.Println("すべての処理が完了しました。")
}
こちらが実行結果になります。
コードの解説
まず、wgという名前のWaitGroupインスタンスを作成しています。
sync.WaitGroup は、goroutine(並行処理の単位)の完了を待つための仕組みです。
その次は、numProcesses変数に並行して実行する処理の数を設定しています。
次に、forループを使って指定された数だけgoroutineを作成しています。
各goroutineは、go func(id int) の形で無名関数として定義されています。
idパラメータは、各goroutineの識別子となってます。
defer wg.Done() は、goroutineが終了したことを WaitGroup に通知します。
fmt.Printf を使って、処理の開始と完了を表示しています。
time.Sleep(time.Second) は、1秒間スリープを表しています。実際は必要ありませんが、今回は並行処理をわかりやすくするために実装しました。
そして、wg.Wait() を呼び出すことですべてのgoroutineが順次終了します。
すべてのgoroutineが完了後、すべての処理が完了しました。と表示されます。
最後に
質問、ご指摘ありましたらいつでもお待ちしております。
最後までお付き合いくださりありがとうございました。