Go言語

Go言語で並行処理を始める前に: goroutineとchannelの基礎

ⓘ本ページはプロモーションが含まれています

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


スポンサードリンク

Go言語で並行処理を始める前に

Go言語の並行処理技術は、現代のアプリケーション開発において重要なスキルです。特にgoroutineとchannelという仕組みにより、複数のタスクを効率的に扱えるのが特徴です。しかし「並行処理」と「並列処理」は混同されがちで、それぞれ異なる概念です。このセクションでは、Go言語がなぜ並行処理に適しているのか、そして基本的な仕組みを整理します。

並行処理の必要性とGoの特徴

並行処理は、複数のタスクを同時に実行する技術であり、特にI/O待ちや計算リソースの非効率利用を解消します。Go言語では、軽量なgoroutineと安全なデータ共有が可能なchannelという仕組みで、並行処理を簡単に実装できます。
一方で並列処理は、複数のCPUコアで同時に処理を行う技術です。これらを混同すると設計ミスにつながるため、区別することが重要です。

並行処理とは?

  • 定義: 複数のタスクを「実行順序」に従って効率的に切り替える技術
  • 目的: 非ブロッキングI/O対応・リソース最適化
  • 特徴:
  • タスクスイッチングが軽量で高速
  • データ共有はchannel経由で安全

Go言語の特徴

  • goroutine: 軽量な協調的マルチタスク
  • channel: 安全なデータ共有機構
  • 設計哲学: 「軽量なタスク管理」と「データ共有」の両立を目指す

goroutineの仕組みと基本構文

goroutineはGo言語特有の並行処理単位で、関数呼び出しと同じように簡単に起動できます。しかし、その背後には「協調的マルチタスク」が働いています。

関数呼び出しで簡単に起動できる軽量な並行処理

Go言語ではgo keywordを使ってgoroutineを開始します。例えば以下のコードは、2つのgoroutineを同時に実行します。

このコードでは、sayHello()sayBye()が並行して実行されます。ただし、main関数の終了時にgoroutineが未完了でもプログラムは終了するため、sync.WaitGroupなどの同期手段が必要です。

goroutineのライフサイクル管理

ステップ 説明
1. 実行開始 go keywordで関数呼び出し
2. 処理実行 単独のスタックとメモリ領域を持つ
3. 終了判定 関数が正常終了するか、戻り値がない場合に自動終了

注意点:goroutineが長時間走り続ける場合、「リーク」してしまう可能性があります。後述のベストプラクティスで詳しく解説します。


channelによる安全なデータ共有

goroutine間でデータを送信する際、channelを使うと競合状態や不正アクセスを防げます。これはGo言語の最大の特徴とも言えます。

チャネルの宣言と基本操作

チャネルはchanキーワードで宣言し、送受信には<-演算子を使います。以下が基本的な例です。

このコードでは、goroutineがチャネルに文字列を送信し、main関数側でそれを受け取って表示しています。

バッファード/ノンバッファードチャネルの違い

種類 特徴
バッファード 一定量のデータを一時的に保存可能(make(chan int, 10)
ノンバッファード データが即座に送信される。受信側がないとブロックされる

ベストプラクティス:同期が必要な場合、ノンバッファードチャネルを、I/O待ちなど非同期処理ではバッファードチャネルを使うと効率的です。


selectステートメントによる複数チャンネル処理

複数のチャネルを同時に監視するにはselectステートメントが有効です。これは、ネットワーク通信やタイムアウト処理などで活用されます。

複数チャネルの同時監視機能

以下はselectを使う例です。どちらかのチャネルからデータが送信されると実行されます。

このコードでは、どちらか一方のチャネルからデータが送信された瞬間に処理が実行されます。

defaultケースの活用法

selectにはdefault句を追加して「いずれもブロックしない」状態でも処理できるようにします。例えばタイムアウトを設定する場合に使われます。

非ブロッキングの重要性defaultを使うことで、処理が待たずに進めるように設計できます。


並行処理のベストプラクティス

goroutineやchannelの使用にはいくつかの注意点があります。特に「リーク」や「チャンネルクローズ」はミスを起こしやすいポイントです。

goroutineリークの回避方法

  • 理由: goroutineが終了せずに残るとリソースを浪費します。
  • 対策:
  • sync.WaitGroupでgoroutineの終了を待つ
  • コンテキスト(context)を使ってキャンセルする

適切なチャンネルクローズのタイミング

情報 解説
送信側がクローズ データがなくなったときにclose()を呼び出す
受信側はブロック解除 for range chで安全に受信可能
クローズのタイミング 1. データ送信終了後 2. 受信側が処理終了した時点でクローズ

テストの重要性: 並行処理はデバッグが難しいため、ユニットテストやプロファイリングツール(例: pprof)を使うと効率的です。


練習問題で理解を深める

ここまでの解説をもとに、実際にコードを書いてみましょう。以下の問題に挑戦することで、並行処理の仕組みがより実感できます。

基礎レベルのコード完成課題

以下は不完全なコードです。chでデータを受け取るように修正してください。

ヒント: <-chを使ってください。main関数の終了を待つため、time.Sleep()sync.WaitGroupも考慮してください。

チャネル同期を使った応用問題

次のコードは、2つのgoroutineでカウントアップを行うものです。結果として**「1, 2」の順に表示されるように修正してください。

ヒント: シーケンシャルに実行するには、chで同期を取る必要があります。sync.WaitGrouptime.Sleep()でgoroutine終了を待つことも検討してください。


高度な課題: チャネルクローズの制御

以下のコードは、チャネルが正しくクローズされているか確認するものです。close(ch)を適切に配置し、リークを防ぐように修正してください

ポイント:

  1. worker関数内で送信終了後にclose(ch)を実行
  2. main関数でfor range chを使って受信し、クローズを検知

補足: チャネルクローズのベストプラクティス

ケース 推奨処理 理由
送信終了時 close(ch) 受信側がブロックを解除するため
受信完了時 なし チャネルクローズは送信側の責任
複数送信者がある場合 1人だけがクローズ 多重クローズによるエラー回避

注意: 受信終了後、チャネルをクローズする必要はありません。送信終了時にのみクローズしてください。


スポンサードリンク

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


-Go言語