目次へ

11. 並行処理

Do not communicate by sharing memory; instead, share memory by communicating.

11.1 goroutine

Goでの並行処理モデルは goroutine と呼ばれています。
goroutineには次の特徴があります。

  • goステートメントによって独立実行される関数です。
  • ネイティブスレッドよりも小さなメモリ使用量です。
  • ネイティブスレッドと同様に個別のコールスタックを持つ。
  • 低コストで実行可能なため、数千から数十万のgoroutineの実行が可能です。

goroutineを使って並行処理をしてみましょう。
並行処理にしたい関数の前に go をつけるだけです。

go list.Sort()   // list.Sort() が並行処理として実行されます。

並行処理している間にmain()が終了すると、goroutineの実行状態にかかわらずプロセスが終了します。

package main

import (
    "fmt"
    "time"
)

func say(s string){
    for i := 0; i < 5; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
}

func main(){

    // 並行実行となる
    go say("Gopher")

    // 通常実行
    say("Hello")
}

以下の用にGopherとHelloが表示されれば成功です。

Gopher
Hello
Hello
Gopher
Gopher
Hello
Hello
Gopher
Gopher
Hello
Edit
Channel

11.2 channel

goroutineとのコミュニケーション手段としてchannelがあります。

channelの初期化はmakeで行います。
また、chan intとすることでint型のchannelを定義しています。

// Declaring and initializing.
var c chan int
c = make(chan int)
// or
c := make(chan int)

channelでの送信

c <- 1

channelでの受信

// "<-" はデータフローの向きを示します
value = <- c

channelはバッファを持つものと持たないものがあります。

バッファを持たないchannelは同期的にコミュニケーションが行われます。
1度channelを送信すると、受信されるまで送信はブロックされます。

c := make(chan int, 0)   // バッファなし(0がバッファ)

バッファを持つchannelはセマフォのように使用できます。
channelの送信は受信の有無にかかわらずバッファ数までブロックされずに送信できます。
1つ受信される毎に1つ送信できるようになります。

c := make(chan int, 100) // バッファあり(100がバッファ)

channelを用いたプログラム

package main

import (
        "fmt"
)

func main() {

        c := make(chan int)
        done := make(chan bool)

        go func() {
                for i := 0; i < 10; i++ {
                        // cチャネルに送信
                        c <- i
                }
                // doneチャネルに送信
                done <- true
        }()

        fmt.Println("start")

        for {
                select {
                case v := <-c: // cチャネル受信
                        fmt.Println(v)
                case <-done: // doneチャネル受信
                        fmt.Println("done")
                        return
                }
        }

}

実行結果

start
0
1
2
3
4
5
6
7
8
9
done

goroutineとchannelによって並行処理を簡単に記述することができました。

↑このページの先頭へ

こちらもチェック!

PR
  • XMLDB.jp