diff -c x14b.c x14be.c(TrueColorディスプレイ対応版) |
|
x14be.cの実行 |
|
先週までは、イベント駆動型のクライアントの作成方法に ついて説明してきました。 今週は、実時間動作を行なうクライアントの作成方法に 関して説明します。
X Window System ではサーバとクライアントの間の通信効率を上げるために、 クライアントはできるだけ要求をまとめて X サーバに送り出そうとします。 したがって、Xlib の関数を呼び出したからといってその瞬間に Xサーバに要求が送られるわけではありません。 このため、「関数を呼び出したタイミング」と、 「その関数によって生成された要求がXサーバに実際に 送られるタイミング」 とがずれてしまいます。
XクライアントがXサーバに送る要求は クライアントのバッファに一時的に蓄えられていて、
そのため、ある瞬間にXサーバの要求が送り出されることを 保証するためには、バッファ内の要求を送り出す関数である
X Window Systemのアプリケーションの多くは、 「イベントが送られて来るまでずっと待ち、 送られてきたらそのイベントを処理する」という 『イベント駆動型 (event-driven)』の動作を行います。
イベント駆動型のプログラム |
|
一方、反射神経ゲームのように実時間動作するプログラムでは、 イベントがこなくても一定時間ごとに次の状態に移るための 計算を行なう必要があります。 このために「一定時間が経過するのを待つ(時間をつぶす)」 必要がありますが、時間待ちの間は一旦制御をOSに帰すべきです。 「ある時刻が来るのを待つ」ときに「動作時刻が来るまで 単に時間を調べながらループを回る」ようなことは マルチタスク環境では決して行ってはいけません。 単純なループを回るだけのプログラムは、CPU時間を大量に浪費し、 他のアプリケーションの実行に悪影響を与えます。 残念なことに、ときどきX Window System上のツールやゲーム などでいい加減な作り方をされたものを見掛けることがありますが、 そのような質の低いプログラムは自分は書かないようにしましょう。
待ち時間の間一旦制御をOSに帰すには
select()を使った場合は以下のようになります。
selectを使って待つ |
|
Xサーバとの通信に使っているソケットは ConnectionNumber(dpy) で 得ることができます。本来は select() で待つと Xサーバからの イベント・パケットが存在するかどうかは以下のようにして 得られるはずです。
xselect1.c |
|
しかし、システムによってはサーバから送られてきたイベントを できるだけ読み込んで(readして)しまうことがありますので (SystemV系のUnixなど)、 XNextEvent()などブロックする可能性のある関数を呼び出すよりは、 XCheckIfEvent(), XCheckMaskEvent(), XCheckTypedWindowEvent(), XCheckWindowEvent()などブロックしない関数を用いるほうがよい ようです。
xselect2.c |
|
select() を使ってリアルタイム動作を行うプログラムを ネットワーク対応にするのは比較的簡単です。 この講義の冬学期前半(第1回〜第5回)で使った tcp.c を 利用して説明します。
realtime2.c |
|
[1] 先週作成した k14b.c を変更し、さらに別の16x16ドット程度の 画像が0.5秒毎にランダム・ウォーク(16ドット程度ずつ乱数で上下左右に 移動してゆく)するように変更して下さい。 ファイル名は x15.c としましょう。
(ヒント)乱数を発生させるには以下のようにします。
rand.c |
|
(ヒント2)上下左右のランダムウォークを決定するには、発生させた乱数を 4で割った余りで判断すればよいでしょう。
rand2.c |
|
課題が完成したら、x15.c を Subject: に Report と書いて p2r13@nw.tsuda.ac.jpへ送って下さい。 コンパイルできなかったり、きちんと動作しないものを送っても 提出とは認めません。
上記の Email アドレス宛に送ったメイルは http://nw.tsuda.ac.jp/cgi-bin/cgiwrap/p2r13/mailhead でヘッダ部が参照できますので、Emailを送ったあとで 正しく提出されたかどうか必ず確認しておいて下さい。
提出期限は来週木曜日 8:50a.m. です。