Contenu connexe Similaire à Goroutineと channelから はじめるgo言語 (8) Goroutineと channelから はじめるgo言語2. アジェンダ
● 自己紹介
● Goとは?
● Goroutineの基本
● GoroutineとChannel
● 複数のChannelを扱う
● ファーストクラスオブジェクト
● 単方向のChannel
● for-selectパターン
5. Concurrency is not Parallelism
■ ConcurrencyとParallelismは違う
● Concurrency => 並行
● Parallelism => 並列
■ Concurrency
● 同時にいくつかの質の異なる事を扱う
■ Parallelism
● 同時にいくつかの質の同じ事を行う
by Rob Pike
6. Concurrency is not Parallelism
■ Concurrency
■ Parallelism
本を運ぶ
本を燃やす
台車を運ぶ
本を積む
本を燃やす 本を燃やす 本を燃やす 本を燃やす
11. 共有の変数を使う
func main() {
done := false
go func() {
time.Sleep(3 * time.Second)
done = true
}()
for !done {
time.Sleep(time.Millisecond)
}
fmt.Println("done!")
}
共有の変数を使う
http://play.golang.org/p/mGSOaq4mcr
13. 共有の変数を使う
n := 1
go func() {
for i := 2; i <= 5; i++ {
fmt.Println(n, "*", i)
n *= i
time.Sleep(100)
}
}()
http://play.golang.org/p/yqk82u0E4V
for i := 1; i <= 10; i++ {
fmt.Println(n, "+", i)
n += 1
time.Sleep(100)
}
競合
19. Channelの基本
■ 初期化
■ 送信
■ 受信
ch1 := make(chan int)
ch2 := make(chan int, 10)
ch1 <- 10
ch2 <- 10 + 20
n1 := <-ch1
n2 := <-ch2 + 100
容量を指定
受け取られるまでブロック
一杯であればブロック
送信されまでブロック
空であればブロック
make(chan int, 0)と同じ
20. Channelの基本
func main() {
done := make(chan bool) // 容量0
go func() {
time.Sleep(time.Second * 3)
done <- true
}()
<-done
fmt.Println("done")
}
送信されるまでブロック
http://play.golang.org/p/k0sMCYe4PA
23. select-case
func main() {
ch1 := make(chan int)
ch2 := make(chan string)
go func() { ch1<-100 }()
go func() { ch2<-"hi" }()
select {
case v1 := <-ch1:
fmt.Println(v1)
case v2 := <-ch2:
fmt.Println(v2)
}
}
http://play.golang.org/p/moVwtEdQIv
先に受信した方を処理
24. nil Channel
func main() {
ch1 := make(chan int)
var ch2 chan string
go func() { ch1<-100 }()
go func() { ch2<-"hi" }()
select {
case v1 := <-ch1:
fmt.Println(v1)
case v2 := <-ch2:
fmt.Println(v2)
}
}
http://play.golang.org/p/UcqW6WH0XT
nilの場合は無視される
ゼロ値はnil
26. Channelを引数や戻り値にする
func makeCh() chan int {
return make(chan int)
}
func recvCh(recv chan int) int {
return <-recv
}
func main() {
ch := makeCh()
go func() { ch <- 100 }
fmt.Println(recvCh(ch))
}
http://play.golang.org/p/vg2RhcdNWR
27. 双方向のChannel
func makeCh() chan int {
return make(chan int)
}
func recvCh(recv chan int) int {
go func() { recv <- 200 }()
return <-recv
}
func main() {
ch := makeCh()
go func() { ch <- 100 }()
fmt.Println(recvCh(ch))
}
http://play.golang.org/p/6gU92C6Q2v
間違った使い方ができる
28. 単方向のChannel
func makeCh() chan int {
return make(chan int)
}
func recvCh(recv <-chan int) int {
return <-recv
}
func main() {
ch := makeCh()
go func(ch chan<- int) {ch <- 100}(ch)
fmt.Println(recvCh(ch))
}
http://play.golang.org/p/pY4u1PU3SU
受信専用のChannel
送信専用のChannel
32. まとめ
■ GoroutineでConcurrencyを実現
● go f()で簡単に作れる
■ Channelでやりとりする
● 送受信時のブロック
● ファーストクラスオブジェクト
● 単方向のChannel
■ for-selectパターン
● Goroutineごとに無限ループを作る
● メインのGoroutineはselectで結果を受信
34. 何か作って記事を書こう
■ Go Advent Calendar
● http://qiita.com/advent-calendar/2015/go
● http://qiita.com/advent-calendar/2015/go2
● http://qiita.com/advent-calendar/2015/go3
誰かgo4とgo5を!