Golangでの並列処理サンプル

Page content

例1

1000個のgoroutineでsomekeyを更新するプログラムで、更新する際にsync.Mutexでロックをかける。

package main

import (
    "fmt"
    "sync"
    "time"
)

type SafeCounter struct {
    v   map[string]int
    mux sync.Mutex
}

func (c *SafeCounter) Inc(key string) {
    c.mux.Lock()
    c.v[key]++
    c.mux.Unlock()
}

func (c *SafeCounter) Value(key string) int {
    c.mux.Lock()
    defer c.mux.Unlock()
    return c.v[key]
}

func main() {
    c := SafeCounter{v: make(map[string]int)}
    for i := 0; i < 1000; i++ {
        go c.Inc("somekey")
    }
    time.Sleep(time.Second) // 待たないとと、974, 949などの値が出てくる
    fmt.Println(c.Value("somekey"))
}

例2

例1はtime.Sleep関数で1000個のgoroutineを待っていたが、sync.WaitGroupを使って、1000個のgoroutineが全部終了するのをまつこともできる。 例1のmain関数の部分だけを修正する。

func main() {
    c := SafeCounter{v: make(map[string]int)}

    var wg sync.WaitGroup
    for i := 0; i < 1020; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            c.Inc("somekey")
        }()
    }
    wg.Wait()
    fmt.Println(c.Value("somekey"))
}
About Wang Zhijun
機械学習好きなプログラマー