English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Go言語にはGoroutinesと呼ばれる特別な機能があります。Goroutineは関数またはメソッドは、プログラムに存在する他のすべてのGoroutineと独立して同時に実行できます。他の言葉で言えば、Go言語で同時に実行される活動をGoroutinesと呼びます。Goroutineを軽量なスレッドと見ることができます。スレッドに比べて、Goroutineの作成コストは非常に小さいです。それぞれのプログラムには少なくとも1つのGoroutineが含まれており、そのGoroutineはメインのGoroutine。もしメインのGoroutineが終了すると、その下に実行されているすべてのGoroutineも終了します。したがって、プログラムに存在するすべてのgoroutineも終了します;Goroutineは常にバックグラウンドで実行されます。
関数やメソッドの呼び出しの前にgoキーワードを使用するだけで、自分のGoroutineを作成できます。以下の文法のように示されています:
语法:
func name(){ // 文 } // 関数名の前にgoキーワードを使用します go name()
package main import "fmt" func display(str string) { for w := 0; w < 6; w++ { fmt.Println(str) } } func main() { // Goroutineの呼び出し go display("Welcome") //通常の関数呼び出し display("oldtoolbag.com") }
出力:
oldtoolbag.com oldtoolbag.com oldtoolbag.com oldtoolbag.com oldtoolbag.com oldtoolbag.com
上記の例では、以下のようにdisplay()関数を修正し、この関数を2つの異なる方法で呼び出します。最初はGoroutine、つまりgo display("Welcome")、次に通常の関数呼び出し、つまりdisplay("w3codebox")
ただし、問題があるかもしれないことに気づくかもしれません。それは通常の関数の結果のみを表示し、Goroutineの結果は表示されません。なぜなら、新しいGoroutineの実行中にGoroutineの呼び出しがすぐに返されるからです。通常の関数のようにGoroutineが完了するまで待つことはありません。彼らは常にGoroutineの呼び出しの後から次の行まで進み、Goroutineが返す値を無視します。したがって、Goroutineを正しく実行するために、以下のコードのようにプログラムにいくつかの変更を行いました:
修正後のGoroutine例:
package main import ( "fmt" "time" ) func display(str string) { for w := 0; w < 6; w++ { time.Sleep(1 * time.Second) fmt.Println(str) } } func main() { // Goroutineの呼び出し go display("Welcome") //通常の関数の呼び出し display("w3codebox") }
出力:
Welcome w3codebox w3codebox Welcome Welcome w3codebox w3codebox Welcome Welcome w3codebox w3codebox
プログラムにSleep()メソッドを追加し、新しいGoroutineの実行中にメインGoroutineが待機するようにしました。1秒間スリープします。1秒まで続きます。その後、スクリーンに歓迎メッセージを表示し、1秒のメインGoroutineが再スケジューリングし、操作を実行した後終了します。このプロセスはzの値が<6その後、メインGoroutineが終了します。ここでは、Goroutineと通常の関数が同時に動作します。
Goroutineはスレッドよりもコストが低いです。
Goroutineはスタックに格納されており、スタックのサイズはプログラムの要求に応じて増大・縮小することができますが、スレッドではスタックのサイズは固定です。
Goroutineはチャネルを使用して通信を行い、これらのチャネルは特別に設計されており、Goroutineが共有メモリにアクセスする際に競合を防ぐことができます。
プログラムが1つのスレッドを持っており、そのスレッドには多くの関連するGoroutineがあると仮定します。もし、リソースの要求によりどのGoroutineもスレッドをブロックした場合、残りのすべてのGoroutineは新しいOSスレッドに割り当てられます。これらの詳細はプログラマーには隠されています。
Go言語では、匿名関数をGoroutineとして起動することもできます。つまり、goキーワードを使用して関数の前頭に付けることで、以下の文法のように匿名Goroutineを作成できます:
语法:
//匿名関数の呼び出し go func(parameter_list){ // 文 )(arguments)
package main import ( "fmt" "time" ) func main() { fmt.Println("Welcome!! to Main function") //匿名Goroutineの作成 go func() { fmt.Println("Welcome!! to oldtoolbag.com") }) time.Sleep(1 * time.Second) fmt.Println("GoodBye!! to Main function") }
出力:
Welcome!! to Main function Welcome!! to oldtoolbag.com GoodBye!! to Main function