10Goの並行処理パターンを使って速攻で分かった気になるGogoroutineこの記事はチームラボエンジニアリングアドベントカレンダー10日目の記事です。Java逆引きレシピを片手に理解するでした。はじめに趣味でGoを触るようになって半年ぐらいは経ったと思います!こんなにハマったのは並行処理がめちゃくちゃ面白かったからです。並列処理は複数人が仕事を同時にこなす事です!並行処理はあくまで処理を同時に行ってはいないんです。この様に処理を切り替えて行います。(人の目には同時に見える)それに比べ、並列処理は処理を同時に行っています。これが並行と並列のザックリとした違いです。ランタイムによって管理される軽量スレッドです。実行するかのごとく利用することが可能で、かつそれを簡単な構文で実現できます。個人的にはこの説明が一番しっくり来ました!詳しい説明はここでは行いませんが、goroutineの大元はメルヴィン・コンウェイさんのcoroutineの考え方を参考にしているみたいです!syncパッケージまあ大枠はここまでにして(自分が説明するより良記事がある)早速実際に動かしてみましょう!syncパッケージはGoの標準パッケージに用意されています。相互排他ロック(チャネルのブロックの様な動き)をしてくれたり、複数のゴルーチンを扱う上でブロックを提供してくれたりします。goroutineってほっとくと簡単に終わってしまったり(厳密には消えないけど)想定と違うタイミングで変数を上書きする事もあります。}()}"Hello"が出力されないんです!ここでのgoroutineはメインゴルーチン(main関数)によって生成されているので、メインゴルーチンが終わると終わってしまいます。Pool型などなどが挙げられると思いますが、ここら辺の記事はたくさんあるのでそちらを見て見てください。channel並行処理を使う上で通信によってメモリ共有を提供してくれる代物です。チャネルの説明としてとても分かりやすかったのが水が流れる川のように、チャネルは情報の流れの水路として機能します。渡され、そこから下流に読み込まれます。本当にこの通りでストリームの考え方と近いかも知れません。Goの設計思想でも下記の様に述べられています。communicating.メモリを共有することで通信しようとしないこと。代わりに通信することでメモリを共有すること。チャネルのクセとか並行処理で気をつける事とかあれこれこの後からはすぐに使える並行処理パターンを紹介していきます!その前に最低限のチャネルの特性や並行処理で気をつける事などを抑えておきましょう。ブロックチャネルはブロックして、待つ事が出来ます。<-stringStreamの部分が検知する事が出来ます。配列と同じ様にチャネルもrangeで回す事が出来ます。fmt.Println(str)}rangeのfor文も先程と同じ様に、closeを検知してループが終了します。バッファ付きチャネルは宣言時に決めたn個が入るまでブロックされます。up")}select文はどのチャネルが準備出来たかを評価します。どのチャネルも準備出来ていない場合はselect文全体がブロックします。これはイメージ湧きづらいと思うので、並行処理パターン紹介の時に出て来た時にみて見てください!チャネルには読み込み専用と書き込み専用とその両方行えるものがあります。どのチャネルにどの権限を与えるかもしっかりと考えた方が良いです。便利な事に以下の様にして権限の割り振りが出来ます。普通に渡せる!使ったら片付ける!goroutineってほっとくと簡単に終わってしまったり(厳密には消えないけど)想定と違うタイミングで変数を上書きする事もあります。先程上で厳密には消えないと述べましたが、これには理由があります。ゴルーチンはランタイムによってガベージコレクションされないので片付け無ければなりません。軽量だからと言って放置する事は思わぬメモリリーク(ゴルーチンリーク)を引き起こす事になりかねません。あるgoroutineがgoroutineの生成の責務を担うのであれば、そのgoroutineを停止出来るようにする責務も担わなくてはなりません。(名言)goroutine生成元(親)から子への終了のシグナルには慣習としてdoneという名前の読み込みチャネルにします。インターフェイス型はgolangのコミュニティでも敬遠されるイメージがありますが、doneチャネルに関しては問題無いかと思ってます。5秒後に終了するこんな風に親から子を終了させます。任意のタイミングで複数のgoroutineを(ほぼ)同時に終了させることも簡単に出来ますね!並行処理パターンお待たせしました!ちょっと長くなりましたが、明日から使える並行処理パターンを紹介していきます。並行処理パターンではステージを並べたパイプラインを意識します。ステージは受け取るものと返すものが同じ型でなければなりません。パイプラインを使う事で各ステージでの懸念事項を切り分けることが出来ます。ステージとか言われてもなんやよう分からんですよね。そこで最初に意識して欲しいのはジェネレーターです。パイプラインの始めにはチャネルへの変換を必要とするデータの塊が必ずあるはずです。その責務を担うのが、ジェネレーターです。fmt.Println(v)}これが並行処理の基本の一連の流れです!雛形とまでは言えませんが、中の処理を変えるだけで、様々な処理が出来ると思います。doneチャネルこの要点を抑えるだけで綺麗な並行処理を行う事が出来ます!これがパターンです!!!笑ステージをもっと増やして組み合わせても問題ありません。fmt.Println(v)}自身もまだまだなので間違いがあるかも知れませんが、温かく見守って頂ければと思います。最後までありがとうございました!明日の記事はyanananaさんによるジェネリクスを見ても逃げないです。upLoginユーザーは見つかりませんでした。