goでスレッド処理する。


はじめに

Go言語でスレッド処理について
やったメモを記載します。

実践

単純なスレッド

以下のmain関数内のthread()の処理部分をスレッドさせます。

main.go
package main

import (
    "fmt"
    "time"
)

func thread() {
    time.Sleep(time.Microsecond * 100)
    fmt.Println("test")
}

func main() {
    thread()
}

例えば以下のようにgoとつけることで、スレッドできますが、処理が終わる前にメイン処理が終わってしまうため
実行しても何にも表示されません。

main.go
package main

import (
    "fmt"
    "time"
)

func thread() {
    time.Sleep(time.Microsecond * 100)
    fmt.Println("test")
}

func main() {
    go thread()
}

実際に、channelsの機能を使用して、スレッドの処理がおわるまで処理させる場合は以下のように変更します。

main.go
package main

import (
    "fmt"
    "time"
)

func thread() {
    time.Sleep(time.Microsecond * 100)
    fmt.Println("test")
}

func main() {
    ch1 := make(chan bool)
    go func() {
        thread()
        ch1 <- true
    }()
    <-ch1
}

複雑な処理

以下のように、0~100までの数をnとしたときに、0~nまでの数を和を求めるものとします。

main.go
package main

import "fmt"

func thread(num int) int {
    output := 0
    for i := 0; i < num; i++ {
        output += i
    }
    time.Sleep(time.Microsecond * 10)
    return output
}

func main() {
    output := []int{}
    for i := 0; i < 100; i++ {
        tmp := thread(i)
        output = append(output, tmp)
    }
    fmt.Println(output)
}

もし、同じ結果を得るような内容のスレッド化する場合は、以下の通りになります。

main.go
package main

import (
    "fmt"
    "time"
)

func thread(num int) int {
    output := 0
    for i := 0; i < num; i++ {
        output += i
    }
    time.Sleep(time.Microsecond * 10)
    return output
}

func main() {
    output := make([]int, 100) //スレッドの処理結果格納場所を確保
    ch := make(chan bool, 100) //同時に処理できる数
    for i := 0; i < 100; i++ {
        ch <- true
        go func(num int) {
            tmp := thread(num)
            output[num] = tmp
            <-ch
        }(i)
    }
    for {
        if len(ch) == 0 {
            break
        }
        time.Sleep(time.Microsecond)
    }
    fmt.Println(output)
}

現時点では、100スレッドまで同時に処理できるようにできますが、ハードウェアの処理できる数によっては
chの確保数を減らせば、同時に処理できる数を変更できます。
また、スレッド内の処理結果の値をメインで使用したい場合は、あらかじめ格納場所は指定してください
appendなどの関数を使用すると結果がおかしくなることが多いです。