Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

C/C++でコルーチンを実装する方法をわかりやすく解説

この記事では、C/C++におけるコルーチン(coroutines)の仕組みについて、実際のサンプルプログラムを通じて解説します。

コルーチンとは、2つのルーチン間で実行の制御を相互に切り替えることができる特殊な制御命令のことです。通常の関数呼び出しでは、呼び出された関数が完了すると制御は必ず元の呼び出し元に戻りますが、コルーチンでは処理を中断した地点の状態を保持したまま制御を渡し、次回の呼び出し時にその続きから実行を再開できます。この特性を活かすことで、イテレータや協調的マルチタスクなどが実装可能になります。

標準のC言語にはコルーチン構文が用意されていないため、ここでは static変数switch文 を組み合わせることで、コルーチンのような動作をシミュレートする手法を紹介します。

サンプルコード

#include<stdio.h>
int range(int a, int b){
   static long long int i;
   static int state = 0;
   switch (state){
   case 0:
      state = 1;
      for (i = a; i < b; i++){
         return i;
      //ここで制御をmainに返す
      case 1:; //次回呼び出し時にここから実行を再開
      }
   }
   state = 0;
   return 0;
}
int main(){
   int i;
   for (; i=range(1, 5);)
      printf("control at main :%d\n", i);
   return 0;
}

実行結果

control at main :1
control at main :2
control at main :3
control at main :4

コードの解説

このプログラムのポイントは、以下の2つのstatic変数にあります。

  • static long long int i:ループカウンタの値を関数呼び出し間で保持します。
  • static int state:現在の実行状態(どのcaseから再開するか)を記憶します。

初回呼び出し時は state が 0 なので case 0 から実行が始まり、for ループの1周目で return i により制御が main 関数へ戻ります。このとき、switch 文の内側に case 1 を配置することで(Duff's deviceと呼ばれる手法)、次回呼び出し時にはループの途中から処理を再開できる仕組みです。

範囲の終端に達すると state が 0 に戻り、関数は 0 を返して終了します。これにより、main 側の for ループも終了します。実行結果を見ると、1から4までの値が1つずつ main に渡されていることが確認でき、まさにコルーチン特有の「中断と再開」の動作が実現できています。

なお、C++20以降では言語仕様としてコルーチン(co_awaitco_yieldco_return)が正式に導入されているため、このようなトリッキーな実装を行わなくても、より安全で可読性の高いコルーチンを記述できるようになりました。


  1. C/C++のセグメンテーションフォルト(コアダンプ)とは?主な原因と具体例を解説

    本記事では、C/C++プログラミングにおける「コアダンプ(セグメンテーションフォルト)」について、その発生原因と具体的なコード例を交えてわかりやすく解説します。 セグメンテーションフォルトとは セグメンテーションフォルト(Segmentation Fault)とは、プログラムが許可されていないメモリ領域にアクセスしようとした際に、OSがプログラムを強制終了させる現象です。実行時エラーの中でも特によく発生するもので、「core dumped(コアダンプ)」というメッセージとともに表示されることから、この名前で広く知られています。 主な発生原因としては、次のようなケースが挙げられます。 読み取

  2. C/C++で学ぶAA木(AA Tree)とは?基本概念と平衡化操作を徹底解説

    AA木(AA Tree)とはコンピュータサイエンスにおいて、AA木(AA Tree)とは、順序付きデータを効率的に格納・検索するために実装された平衡木(バランスドツリー)の一種です。AA木は、赤黒木(Red-Black Tree)の変種として扱われます。赤黒木は二分探索木の一形態であり、要素の追加や削除を効率的にサポートします。赤黒木と大きく異なる点は、AA木では赤いノードを右の子としてのみ追加でき、左の子としては配置できないという制約があることです。この制約により、2-3-4木ではなく2-3木をシミュレートすることになり、その結果、木の保守操作が大幅に簡素化されます。赤黒木の平衡化アルゴリズ