web-technical-blog

web開発に関する技術メモ

Go言語のgo文について

go文はdefer文と同様に、関数呼び出し形式の式を受け取ります。
次のプログラムを実行すると、main関数の無限ループと、sub関数の無限ループが
並行して実行され、各々のループが出力される文字列が不規則に表示される

package main

import (
    "fmt"
)

func sub() {
    for {
        fmt.Println("sub loop")
    }
}

func main() {
    go sub() // ゴルーチン開始

    for {
        fmt.Println("main loop")
    }
}

Goは、スレッドよりも小さい処理単位である「ゴルーチン(goroutine)」が並行して動作するように実装されている。
go文は、このゴルーチンを新たに生成して、並行して処理される新処理の流れをランタイムに追加するための機能。
「ゴルーチン」について深く知る為に、runtimeパッケージを使用。
このパッケージはGOのランタイム自身についての情報を参照したり、動作をコントロールしたりするための機能が含まれている。

package main

import (
    "fmt"
    "runtime"
)

func main() {
    fmt.Printf("NumCPU: %d\n",runtime.NumCPU())
    fmt.Printf("NumGoroutine: %d\n", runtime.NumGoroutine())
    fmt.Printf("Version: %s\n", runtime.Version())
}

//Result 
//NumCPU: 2 ← 使用できるCPUのコアの数
//NumGoroutine: 1 ← Goランタイム上で動作しているゴルーチンの数
//Version: go1.7.3
package main

import (
    "fmt"
    "runtime"
)

func main() {
    go fmt.Println("Yeah!") // ← go文を追加してみる
    fmt.Printf("NumCPU: %d\n",runtime.NumCPU())
    fmt.Printf("NumGoroutine: %d\n", runtime.NumGoroutine())
    fmt.Printf("Version: %s\n", runtime.Version())
}

//Result 
//NumCPU: 2
//NumGoroutine: 2
//Version: go1.7.3

結果として、NumGoroutineの値が先ほどの1から2に増加する。
環境やGoのバージョンの違いによっては、必ずしも同様に動作するかは保証できないが、
ゴルーチンがGoのランタイムによって管理されることついては理解が必要。