Your SlideShare is downloading. ×
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会2
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会2

1,760

Published on

0 Comments
17 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,760
On Slideshare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
14
Comments
0
Likes
17
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Goroutineと Channelから はじめるGo言語 ver. 3 2014/1/18(土) @初心者向けgolang勉強会
  • 2. 自己紹介 上田拓也 KLab株式会社 仕事:  ・サーバサイド(PHP)  ・フロントエンド(JS) 学生のころ:  ・セルオートマトン  ・複雑系 twitter : @tenntenn
  • 3. アジェンダ ● Go言語とは ● GorotuineとChannel
  • 4. Go言語とは?
  • 5. Go言語ってなに? ● え?Go言語知らない? ● ビッグウェーブに乗り遅れてますよ! Googleトレンド
  • 6. Go言語とは? ● Googleが開発したコンパイラ言語 ○ その他のGoogleが開発した言語 ■ Dart : JSの代替 ■ noop : JavaVMで動く言語(忘却のかなた) ● 設計者: Robert Grisemer, Rob Pike, Ken Thompson
  • 7. Go言語の特徴 ● シンプルな文法/設計 ○ 曖昧さを排除した設計 ○ 強い静的型付け ○ 型推論ができるので、型を省略できる ○ ポインタはあるがポインタ演算はなし ○ 複数の戻り値を返す関数 ○ ダックタイピング ○ ゼロ値初期化 ● ゴールーチンとチャネル ● 豊富なライブラリ群 ○ goツールは最強 ○ Web系パッケージの豊富さ ○ Google App Engine for go
  • 8. 主なGo言語の勉強会@東京 ● GoCon spring, autumn ○ Go言語の勉強会では一番規模の大きい ○ Go言語の中の人が来る ● 質実Go研 ○ 標準ライブラリを中心にソースを読む会 ○ 少人数で濃い話をする ● 電車でGo! ○ 電車に乗りながらGo言語をする ● Go羅温泉 ○ 強羅温泉でGo言語をする
  • 9. 私とGo言語 ● 研究で使うために始める ○ セルオートマトンシミュレータを作るため ● 主にGDG名古屋で活動していた ○ スタートGo #0, #1 ● CodeIQにて問題を出題 ● 社内でGo会を開催している
  • 10. 初心者向けの情報 ● Tour of Go ○ Web上でGo言語の一通りいじれる ● Go言語の初心者が見ると幸せになれる場所 ○ http://qiita. com/tenntenn/items/0e33a4959250d1a55 045
  • 11. Gorotuine と Channel
  • 12. Concurrency is not Parallelism ● ConcurrencyとParallelismは違う by Rob Pike ○ Concurrency=並行? ○ Parallelism=並列? ● Concurrency ○ 同時にいくつかの事を扱う事 ● Parallelism ○ 同時にいくつかの計算を行なう事
  • 13. Concurrency is... by Rob Pike Rob Pike氏のプレゼンのまとめでは、 ○ Concurrency is powerful. ○ Concurrency is not parallelism. ○ Concurrency enables parallelism. ○ Concurrency makes parallelism (and scaling and everything else) easy. とある。
  • 14. Gorotuineとは? ● Go言語ではゴールーチンを用いてConcurrencyを実 現している ● スレッドに似ている... ○ しかし、もっとCheap(=コストが低い) ○ LinuxやUnixのスレッドとは違う ■ スレッドの上にいくつも乗っている ● 簡単に作成できる ○ 関数呼び出しの前にgoキーワードを付ける ■ go f()
  • 15. go + クロージャ http://play.golang.org/p/4DT57uR4gD package main import "fmt" func main() { go func() { fmt.Println("別のゴールーチン") }() fmt.Println("mainゴールーチン") }
  • 16. 並列度 ● 並列度:GOMAXPROCS ○ 同時に最大で実行可能なCPU数 ● デフォルトでは並列度は1になっている ○ runtime.NumCPU()で利用可能なCPU数が取得 できる ○ runtime.GOMAXPROCS()で並列度を設定する 【例】 runtime.GOMAXPROCS(runtime.NumCPU()) ● 指定した並列度でゴールーチンを動かす ○ あまり増やしても意味がない
  • 17. Goroutine間のデータのやりとりは? Goroutine-1 Goroutine-2 go f1() go f2()
  • 18. 共有の変数を使う? Goroutine-1 Goroutine-2 go f1() go f2() 変数v v = 100fmt.Println(v)
  • 19. Goroutine間のデータのやりとり ● 共有の変数を使う?http://play.golang.org/p/mGSOaq4mcr func main() { done := false go func() { time.Sleep(time.Second * 3) done = true }() for !done { time.Sleep(time.Millisecond) } fmt.Println("done!") }
  • 20. 競合が起きますよね! Goroutine-1 Goroutine-2 go f1() go f2() 変数v v = 100v = 200 競合
  • 21. Goroutine間のデータの競合 // これはダメ!! package main import "fmt" import "time" func main() { n := 1 go func() { for i := 2; i <= 5; i++ { fmt.Println(n, "*", i) n *= i } }() // 続く // 続き for i := 1; i <= 10; i++ { fmt.Println(n, "+", i) n += 1 time.Sleep(500) } } http://play.golang. org/p/NJuV6P7TIf
  • 22. 何が問題なのか?どう解決するの? 【問題】 ● 同時に複数のGoroutineからアクセス ● 競合が起きる 【解決方法】 ● 1つのGoroutineからのみアクセスする ● Channelを使う!
  • 23. Channelを使う Goroutine-1 Goroutine-2 go f1() go f2() ch <- 100 Channel <-ch 100 ● Goroutine間でデータをやりとりするパイプ?のような もの
  • 24. Channelの特徴 ● 送受信するデータの型が決まっている ○ 型を指定してChannelを作る ● 一度に保持できる容量がある ○ 初期化の際に容量を指定、デフォルトは0 ● 送受信の際に相手の応答を待つ ○ 容量が0になると、受信元が受け取るまでブロックされる
  • 25. 送信のブロック Goroutine-1 Goroutine-2 go f1() go f2() ch <- 100 Channel 100 ブロック ● 相手が受信(<-ch)してくれるまで、次に進めない
  • 26. 受信のブロック Goroutine-1 Goroutine-2 go f1() go f2() Channel 100 ブロック ● 相手が送信(ch<-100)してくれるまで、次に進めない <-ch
  • 27. Channelの宣言方法と使い方 ● 宣言 ○ ch := make(chan 型) // 容量0 ○ ch := make(chan 型, 容量) ● 送信 ○ ch <- 100 ○ ch <- "hoge" ■ 容量いっぱいであれば取り出されるの待機する ■ 容量0の場合は常に待つ ● 受信 ○ n := <- ch ■ 送られてくるまで待機する
  • 28. Channelの宣言方法と使い方 http://play.golang.org/p/k0sMCYe4PA func main() { done := make(chan bool) // 容量0 go func() { time.Sleep(time.Second * 3) done <- true }() <-done // 待つ fmt.Println("done") }
  • 29. こういう場合はどうするの? Goroutine-1 Goroutine-2 go f1() go f2() Channel-1 ● ブロックするなら複数のChannelからデータを受け取 れない!? Goroutine-3 <-ch1 Channel-2 go f3() <-ch2 ch1 <- 100 ch2 <- "hoge"
  • 30. selectを使う Goroutine-1 Goroutine-2 go f1() go f2() Channel-1 ● selectを使えば、同時に複数のchannelから受信でき る Goroutine-3Channel-2 go f3() <-ch2 ch1 <- 100 ch2 <- "hoge" select <-ch1
  • 31. selectを使う ● 先に受信可能になったcaseを実行する // Goroutine-1にて select { case v1 := <-ch1: // Goroutine-2から ch1 <- 100 case v2 := <-ch2: // Goroutine-3から ch2 <- "hoge" } ※Channelがnilだとそのcaseは無視:nil channel http://play.golang.org/p/7fNEkf9B8H
  • 32. ReadOnlyとWriteOnly ● 通常のチャネルは双方向 ○ 引数や戻り値で渡す場合は困る func hoge(in chan int) { n := <-in // 入力として使うのが正解! in <- 100 // 間違った使い方ができる! }
  • 33. ReadOnlyとWriteOnly ● ReadOnly ○ in := make(<-chan int) ● WriteOnly ○ out := make(chan<- int) ● キャスト ○ 双方向チャネルはキャストでReadOnlyまたは WriteOnlyに変化できる ○ ch := make(chan int) ○ in := (<-chan int)(ch) ○ out := (chan<- int)(ch)
  • 34. ファーストクラスオブジェクト ● Channelはファーストクラスオブジェクト ○ 変数に入れれる ○ 引数に渡せる ○ 戻り値に取れる ○ ChannelのChannel ● 戻り値として、チャネルを返す関数は多用される ○ timeパッケージ ○ 5分間待つ <-time.After(5 * time.Minute) http://golang.org/pkg/time/#After
  • 35. range ● for文のrangeで送られてくるデータを次々に取 り出せる http://play.golang.org/p/OSSSzRY8GT // 1秒ごとに現在時間を出す for now := range time.Tick(1 * time.Second) { fmt.Println(now) }
  • 36. どう使って行くのか? ● 沢山の独立したゴールーチンがチャネルを使っ てやり取りをする! ○ Concurrencyになる ● ゴールーチンのコストは安いので、沢山作って もそんなに問題ない ○ ※コストが0ではない ● for - selectパターン
  • 37. for - selectパターン Goroutine-1 Channel-1 Channel-2 select for{} Goroutine-2 for{} Goroutine-3 for{} ● 各Goroutineが無限ループになっており、イベントリス ナー的にChannelを使うパターン
  • 38. Gopher君で表すとこんな感じ! ひたすら本を入れる ひたすら本を運ぶ ひたすら台車を運ぶ ひたすら本を燃やす
  • 39. 構成要素の局所的な振る舞いが 相互作用する事によって 複雑な現象を作り出す 複雑系みたいで楽しい!
  • 40. まとめ ● GoroutineはConcurrencyを実現する機構 ○ go f() で簡単に作れる ● ChannelはGoroutine間のデータのやり取りに 使う ○ 送受信のブロック ○ select〜case文 ○ ファーストクラスオブジェクト ○ select - forパターン
  • 41. 時間があまったら https://github. com/tenntenn/StartGo/tree/master/1

×