並列して処理をソフトウェアで処理を実施したい場合があります。
そのときスレッドがなぜ必要なのかを段階を追ってまとめていきたいと思います。

【説明】

一定時間ごとにサービスが実行できるかどうかをチェックするというポーリングをベースにしてプログラムを記述することにします。

●STEP1:サービス1つ実施する
とにかくサービスが実行できるようにしてみます。
1.LEDを点滅させる

int main()
{
...while(1)
...{
......if(0.1s経過したか?)
......{
.........led_turn();
......}
...}
}

int led_turn()
{
...(LEDを点滅させる処理)
}


●STEP2:サービス2つ実施する
実行できるサービスを複数もたせます。
1.LEDを点滅させる
2.1sに1回、液晶パネルに時刻表示を行う★
3.シリアルからのコマンドに応答する★

int main()
{
...while(1)
...{
......if(0.1s経過したか?)
......{
.........led_turn();
......}
......if(1sが経過したか?)
......{
.........write_time();
......}
......if(シリアル受信したか?)
......{
.........command_exec();
......}
...}
}

int led_turn()
{
...(LEDを点滅させる処理)
}
int write_time()
{
...(時刻表示処理)
}
int command_exec()
{
...if(dumpコマンドが指定された)
...{
......dump();
...}
}
int dump()
}
...for(i=0;i...{
......(ダンプ表示)
...}
{


●STEP3:たくさん時間のかかるサービスを中断し他のサービスも実施できるようにします
実行できるサービスを複数もたせます。3.の処理中で実施されるサービスではダンプ出力中に10回に1回の割合で現在の状態を保存しメインループに戻り他1.2.の処理も実施できるようにします。
1.LEDを点滅させる
2.1sに1回、液晶パネルに時刻表示を行う
3.シリアルからのコマンドに応答するして中断して再開も対応★

int main()
{
...int in_dump=0;
...while(1)
...{
......if(0.1s経過したか?)
......{
.........led_turn();
......}
......if(1sが経過したか?)
......{
.........write_time();
......}
......if(in_dump)
......{
.........in_dump = dump(1);
......}
......else if(シリアル受信したか?)
......{
.........in_dump = command_exec(0);
......}
...}
}

int led_turn()
{
...(LEDを点滅させる処理)
}
int write_time()
{
...(時刻表示処理)
}
int command_exec(int in_dump)
{
...if(dumpコマンドが指定された)
...{
......ret = dump(0);
...}
...return ret;
}
int dump(int in_dump)
{
...int i,num;
...static int save_i,save_num;

...if(in_dump)
...{
......i = save_i;
......num = save_num;
......goto loop;
...}
...for(i=0;i...{
loop:
......(ダンプ表示)
....../* 定期的に中断してメインループに戻る。次の再開に備えるために状態を保存 */
......if((i%10)==9)
......{
.........save_i = i;
.........save_num = num;
.........return 1;
......}
...}
...return 0;
}


【問題点】
①他の機能へ処理を明け渡すために、時間のかかる処理に対して中断・再開といった記述を追加する必要がある。
1.今の処理の状態を保存する。
2.再度実施されたとき保存された情報を読み出し続きを実施する。
②プログラムが複雑化するとバグが出やすくなる。要はメインの処理に集中しにくくなる。


【対策の方向性】
①上記の例でいうと「1.LEDを点滅させる」、「2. 1sに1回、液晶パネルに時刻表示を行う」、「3.シリアルからのコマンドに応答する」の定期的な処理の切り替え。
②処理状態の中断、保存、再開の共通化。


【解決策】
実現のための着眼点は前章の割込み処理のときに着目したCPUの特長です。処理状態を保存しておきたいのなら、現在のスタックとレジスタの状態を保存しておけば、処理が再開できるということです。

つまり、各処理の内部で独自に中断、保存、再開を行うのではなく、適当なタイミングで中断させてそのときにスタックとレジスタの状態を保存しておき、また処理を再開できるタイミングでスタックとレジスタの状態を復旧するような処理をすべてのサービスに対して共通的に行えば、処理ごとに対処する必要はなくなるわけです。

これから、その仕様案をKOZOS OSを通して設計・実装していくことになるわけですが、スレッドというキーワードがこれから重要になってきます。