2012年4月26日木曜日

学校では教えてくれないこと | 技術コラム集(組込みの門) | 東電ユークエスト


前回は、マルチタスクとは何か、ということについて簡単に説明したよね。
マルチタスクの仕組みを使いこなすことができれば、複数の処理を効率よく進めることができることがわかってくれたと思う。
でもその一方で、他のタスクと共通の資源(同じファイルに読み書きするなど)を使用する場合には、排他制御を考えないと誤動作を起こしたり、システムが動かなくなったりする場合もあるんだ。

今回は、マルチタスク OS にどのような機能が用意されているのか、どのような場面で使えばよいのかを見ていこう。

例えば、あるタスクで USB のデータを送信するとしよう。
説明を簡単にするため、送信が完了したかどうかは、
USB コントローラのステータスレジスタが「完了」になったかどうかでわかる、とするね。

この場合、単純には以下のプログラムでいけそうだ。

ところが、マルチタスク環境の場合、この方法はお行儀がよいとはいえないんだ。
USBの送信がすぐに終わらないと、その間ループは回り続け、
優先度の低いタスクが実行できないまま、ムダに CPU を使うことになる。
そこで、プログラムを以下のように変更してみよう。


アスピックせずにWindows XP Professionalをインストールする方法

こうすれば、このタスクが休みに入っている間は、優先度の低いタスクに実行権が回るようになる。
このタスクは 20msec ごとに動き、一回のループは普通、CPU を占有する時間はわずかなので、
CPUを有効に使うことができるんだ。

「タスクを一定時間休みにする」機能は一般的に OS のシステムコール(C 言語関数)として標準的に用意されていて、
OS によって名前が違うんだけど、tsk_dly()や sleep()などの関数なんだ。

複数のタスクが分担して処理を行っているとしよう。
タスク A は USB からデータを読み出して、タスク B にデータを渡す。
タスク B はタスク A から渡されたデータを加工して画面に表示する。
このとき、タスク B はタスク A からデータを渡されたことを、どうやって知ることができるのだろうか?

すぐに思いつく方法は、タスク A とタスク B から共通に読み書きできるフラグを作っておいて、
タスク B が定期的にこのフラグをチェックするというものかな。
先ほど使った、タスクを休止させる方法を使ってみよう。


ビニールサイディングのインストール時に管理する方法

タスク A が waitflag を 0 にすると、タスク B はそれを検知して次の処理に進むことができるよね。
うまくいくように思えるけど・・・。ところが、マルチタスク環境ではもっと効率のよい方法が用意されているんだ。
それが、「セマフォ」や「メッセージキュー」などに代表される、イベントを使用する方法なんだ。
これを使うと、「20msec 間隔で休止しつつフラグを定期的に確認する」という処理は必要なくなるんだ。

用途に応じていろいろな手段が用意されているけど、ここでは「セマフォ」を使ってみることにしよう。
セマフォ(semaphore)はもともと、「手旗信号」という意味で、直接の由来は鉄道の「腕木式信号機」であると言われている。「進め」「止まれ」の状態があり、この「進め=実行可能状態」「止まれ=イベント待ち状態」を OS 側でコントロールしてくれるんだ。これを使って先ほどのプログラムを書き換えてみよう。

と簡単になるよね。しかも、セマフォ待ちの命令を実行すると、OS 側がそのタスクを自動的に待ち状態にしてくれる。
そして、タスク A がセマフォを変更すると OS 側はそれを認識し、タスク B のセマフォ待ちを解除して実行可能状態に戻す。
つまり、この間タスク A は全く CPU を使わないから、非常に効率のよいプログラムを書くことができるんだ。


kvmの仕事はどのように行う

セマフォを、タスク間でタイミングの同期を取る手段として使うことを勉強したけど、
実はセマフォにはもうひとつの使い方があるんだ。それは、「排他制御」なんだ。

先ほどの「腕木式信号機」の話に戻るね。信号機は何のためにあるんだろうか?
もちろん、列車が衝突しないように交通整理を行うためだよね。
マルチタスクの世界でも全く同じことが当てはまり、複数のタスク(列車)で共通の資源(線路)を使うためには、
処理(通行)が重ならないように排他制御(交通整理)を行ってやる必要があるんだ。

例えば、タスク A、タスク B から同じバッファにデータを書き込むことを考えよう。
タスク A が書き込んでいる最中にタスク B が書き込みを開始すると、バッファの整合が取れなくなる。
このような場合は、共通の資源であるバッファに対してセマフォを設け、それぞれのタスクが、

というルールを守ってプログラムを作るんだ。こうすると、タスク A が書き込み最中にタスク B に実行権が回っても、
セマフォ待ちのところで停止し、タスク A がセマフォを戻した時点でタスク B がセマフォを取り、
書き込み処理に入るから、同時にバッファに書き込む、という事態を防ぐことができるんだ。


今回はマルチタスクでプログラムを書く場合に使う基本的な機能を紹介してみたけど、これらはほんの一部で、注意しなくてはいけないことはもっともっとあるんだ。
ただ、最後に出てきたセマフォや、今回は書くスペースがなかったメッセージキューなどは、組込みシステムのプログラムには欠かせない基本中の基本なので、市販の書籍や研修などでしっかり理解してほしい。

五の巻:Edianってなに? 七の巻:スタックってなあに?



These are our most popular posts:

タスクスケジューラの状態が『タスクを実行中』のまま終了しない

しかし、稀に下記のような現象が発生してタスクが実行されず困っています。 .... 原因 だとすると、完全に解決するにはどのプロセスがどのファイルをつかんでいるのかを調査 しなければなりませんが、これはなかなか骨の折れる作業のようです。 read more

プリエンプション - Wikipedia

プリエンプション(英: Preemption)は、コンピュータが実行中のタスクを一時的に中断 する動作であり、基本的にそのタスク自体の協力は不要で、後でそのタスクを再実行 するという意味も含む。このような動作をコンテキストスイッチと呼ぶ。 ... どんなシステム 設計でも、プリエンプション不可能な操作が存在する。 ... 協調的マルチタスクは、各 タスクがシステムリソースを必要としないときにそれを自発的に解放するようプログラム されている ... read more

学校では教えてくれないこと

... 場合もあるんだ。 今回は、マルチタスク OS にどのような機能が用意されているのか、 どのような場面で使えばよいのかを見ていこう。 ... こうすれば、このタスクが休みに入っ ている間は、優先度の低いタスクに実行権が回るようになる。 このタスクは 20msec ... read more

Chap3:リアルタイムOSのしくみ - T-Engine Forum Japan

リアルタイムOSの中心的な機能であるスケジューラはどのように実現しているのでしょ うか。 ... 一般的なタスクのスケジューリング方式を以下に示します。 ... 元のタスクが 再びディスパッチされた時に継続して実行できるように、必要なデータを保持しておきます 。 read more

Related Posts



0 コメント:

コメントを投稿