English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Golang 基礎トレーニング

Golang 制御文

Golang 関数 & メソッド

Golang 構造体

Golang スライス & 配列

Golang 文字列(String)

Golang ポインタ

Golang インターフェース

Golang 并行

Golang 異常(Error)

Golang その他の雑項

Go 并行(Goroutines)

Go言語にはGoroutinesと呼ばれる特別な機能があります。Goroutineは関数またはメソッドは、プログラムに存在する他のすべてのGoroutineと独立して同時に実行できます。他の言葉で言えば、Go言語で同時に実行される活動をGoroutinesと呼びます。Goroutineを軽量なスレッドと見ることができます。スレッドに比べて、Goroutineの作成コストは非常に小さいです。それぞれのプログラムには少なくとも1つのGoroutineが含まれており、その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はチャネルを使用して通信を行い、これらのチャネルは特別に設計されており、Goroutineが共有メモリにアクセスする際に競合を防ぐことができます。

  • プログラムが1つのスレッドを持っており、そのスレッドには多くの関連するGoroutineがあると仮定します。もし、リソースの要求によりどのGoroutineもスレッドをブロックした場合、残りのすべてのGoroutineは新しいOSスレッドに割り当てられます。これらの詳細はプログラマーには隠されています。

匿名Goroutine

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