時代はマルチコア
一つのCPUに見せかけて、
複数のCPUが搭載されているのが今のパソコンの主流
せっかくマルチコアなんだし、
プログラミングもマルチコアを活かしたいということで、
Go言語のgoroutine(並行処理)を試してみた。
これで平行処理もばっちりだ。
と言うわけで、
平行処理の練習と解釈の意味を込めて、ここにメモを残す
本来、プログラミングは書いたコードを上から下に向かって順に実行していくもので、
package main
import "fmt"
func main() {
var s string
s = "Hello World!"
fmt.Println(s) //Hello World!と実行される
}
・main内のコードを実行します
・文字列を表示するためのライブラリを読み込んでおきます
・文字列を入れるためにメモリーを空けておきます。空けた領域をsと名付けます
・sにHello Worldという文字列を入れます
・sに入れた文字列を表示します
こんな感じで上から下にプログラムを実行していく。
これだと実行するのにコアが一つで十分で勿体ない。
なので平行で処理しましょ。
と言うことになる
例えば、
1から順に偶数であるか奇数であるかを調べる処理を作ってみる。
まずは普通に書くと
package main
import "fmt"
func main() {
var i int
//1~10まで順に調べる
for {
//10になったらやめる
if i == 10 {
break
}
//偶数の場合
if i%2 == 0 {
fmt.Println("偶数です")
//奇数の場合
} else {
fmt.Println("奇数です")
}
i++
}
}
こんな感じ
これを計算する処理と文字を表示する処理に分けてみる。
この時にchannelという互いの処理を繋ぐ変数を用意しておく必要がある。
計算する処理の方をsenderとし、
結果を受け取り表示するreceiverとしておく
とりあえず、senderとreceiverは置いといて、
先にchannelを用意して、senderとreceiverに突っ込む
func main() {
//偶数の時はchが結果を受け取り、奇数の時はch2が結果を受け取るchannelを用意する
ch := make(chan int)
ch2 := make(chan int)
go sender(ch, ch2)
receiver(ch, ch2)
}
関数名の前にgoと付けて実行すると、他のスレッドを用意して、平行で処理を開始する。
senderで計算した結果を受け取る処理を次の行で実行する。
ここまで書いた上で、senderとreceiverの処理を書いてみると
package main
import "fmt"
func sender(ch chan int, ch2 chan int) {
var i int
for {
//偶数の場合
if i%2 == 0 {
//結果をreceiverに送る
ch <- i
//奇数の場合
} else {
//結果をreceiverに送る
ch2 <- i
}
i++
}
}
func receiver(ch chan int, ch2 chan int) {
//何回実行したか?
var c int
for {
c++
select {
//偶数の結果を受け取った時
case <-ch:
fmt.Println("偶数です")
//奇数の結果を受け取った時
case <-ch2:
fmt.Println("奇数です")
}
//結果を10回受け取ったら終了
if c == 10 {
break
}
}
}
func main() {
ch := make(chan int)
ch2 := make(chan int)
go sender(ch, ch2)
receiver(ch, ch2)
}
こんな感じ
senderでは計算してreceiverに結果を送る。
この時にchannelを使うんだけど、
それをch := make(chan int)で用意する。
(ch2も同様に用意)
それらを各関数に入れて、処理を開始する
senderではreceiverに結果を送らなければならないので、
計算結果を ch <- iという形で<-でchに入れる
一方、receiverではchに入っている値を受け取らなければならないので、
<- chと書いて値を受け取る。
(receiverのchはsenderからの値が送信されるまで待機してくれる)
今回はあえて、偶数であればch、奇数であればch2にして、
receiverの方のselect文で
case <- ch: つまり、偶数のchannelを受け取った時に処理、
case <- ch2: 奇数のchannelを受け取った時の処理の様に分けて書いてみた。
このコードを実行してみると、
偶数です 奇数です 偶数です 奇数です 偶数です 奇数です 偶数です 奇数です 偶数です 奇数です
こうなった。
まぁ、まったくgoroutineが活かされてないけど、
とりあえずマルチコアっぽい処理は書けた。




