Operating System Lecture 11/28
Menu Menu
先週の復習 -- Semaphor, Condition-wait
- Semaphor の使い方
- 待ち合わせの制御
- manual の読み方
Unix でのプロセス間通信と、Real-time 処理
Unix の API (POSIX によって規定されている) による、プロセス間通信と Real-time 処理を調べよう。
問題 (Busy Wait )
以下のプログラムのUnix での問題点を指摘せよ。
for (;;) { if ( c=kbhit() ) process(c); }(kbhit() は、MSDOS で良く使われる、キーボードが押されていたら、そのキーコードを返す関数。Unix のマニュアルには載っていません)
C-FAQ をWWW で探して、kbhit() が Unix では使われない理由を調べよ。
速さと言う点ではどうだろう?
signal による同期
あるイベントで、呼び出される関数を指定する。signal では情報を渡すことはできない。
signal によって中断された system call の取り扱いはどうする? エラーとして良いのか?
socket によるプロセス間通信
基本的には、あっちのプロセスでwriteしたものが、 こちらのプロセスで読めるそれだけ。問題は、
どうやって、相手を指定するのか?である。
共通の親を持つならば、
socketpair, pipeを使うことができる。
共通の親を持たない場合は、
Unix file system の名前空間を使う ネットワークの IP address + Port number を使うという手法がある。前者は、もちろん、ネットワーク経由には使えない。
socket は双方向なので、便利。(pipe は違う)
redirect と pipe
標準入出力の切替えには、close と dup を使う。socket は、Unix に取っては file の一種であり、プロセス毎に番号(file descriptor) で管理されている。
0 標準入力 STDIN 1 標準出力 STDOUT 2 標準エラー出力 STDERRclose して open すれば、その番号が振られる。既に、open されているものをdup (duplicate ) しても良い。
以下は、3年生の shell の課題の一部である。
#include <stdio.h> const int debug=1; main() { char command1[]="wc"; char command2[]="cat /etc/termcap"; int pfd[2]; int save_in; int pid; pipe(pfd); if(pid = fork()){ save_in = dup(0); dup2(pfd[0],0); close(pfd[1]); system(command1); if(debug) fprintf(stderr,"waiting %d\n",pid); dup2(save_in,0); waitpid(pid,NULL,0); if(debug) fprintf(stderr,"done %d\n",pid); return; }else{ if(debug) fprintf(stderr,"forked pid %d\n",getpid()); dup2(pfd[1],1); close(pfd[0]); system(command2); exit(0); } }
socket による通信の待ち合わせ
bind
socket に名前をつけるconnect
TCP connection を張るaccept
TCP connection を受け取るTCP connection を通して、socket channel そのものを渡すこともできる。=> (fork の例題)
サービスモデル
server.pl と client.pl を動かしてみて、サーバの動きを理解しよう。
問題
server.pl を使って、簡単なアクセスカウンター (何回アクセスしたかを数える)を作ってみよ。
サーバ・クライアントモデル
デーモン (daemon )
サービスとトランザクション
サービス内、トランザクション内の並列性Lock をどのように実現しているかを考えよう。
NFS
RPC と UDP という connection less の通信を使って実装されている。lock は、lockd という daemon を使う。
WWW counter
WWW server は fork するので、ファイルを lock することにより同期を取ることが多い。なので、非常に重い。File を配達するだけの WWW server と、CGI を処理するserverを分離するのが効果的。Security 的にも望ましい。
Micro Kernel
OS のサービスのうち、プロセスの作成、削除 スケジュール メモリ管理 プロセス間通信を除くと、その他のサービスは、すべて、サーバによって実現できる。このようにすることによって、OS の最小限必要な部分を抜きだしたものを
Micro Kernelという。
Micro Kernel は、プロセス間通信が増えるので、効率は良くないとされている。しかし、OS の構造の見通しの良さ、拡張性などに利点がある。効率は、プロセス間通信の高速化などによりカバーできる。
Windows NT Mach OS (Mac OS X)などが実用的に使われている。Windows/Mac OS 9は違います。
select による同期
Unix では、select call が万能であり、ほとんどの同期は select を使って実現できる。しかし、ファイルと関係しないので、計算をセーブする場合には、ファイル処理を自分で行なう必要がある。
問題 (keyrecord/keyplay)
real-time application を作ってみよう。「キーボードの入力を時間を含めて忠実に再現する プログラムを作れ」ダメな例
NONBLOCKING モードを使ったread fcntl で設定する良い例
select を使った例を考える サンプルコードを見てみよう select を使わない例を考える ioctl でreadが一文字で戻って来るようにする man termios時間をμsec 単位で測るには?
int gettimeofday(struct timeval *tp, struct timezone *tzp);を使う。
時間は、usleep で稼ぐ。
void usleep(unsigned int microseconds);間違っても100万回ループしたりしない。
keyrecord のサンプルコード RCS って何?
mkdir RCS ci -l co -l rcsdiffkbhit() を Unix で作ってみよう。ダメな例を実装してみて、どれくらいダメか調べよう。
Application の Perfomance Tuning
Performance だけで良いのか? Real-time プログラムにとって Performance とは何か?このkeyrecord の時間の誤差はどこから来るの? Real-time OS とは?
出力ファイルを人間が読めない。出力ファイルを人間が読めるようにするには?
宿題(1) fork する daemon
server.pl を man perlipc などを参考に、fork するように書き換えて見よ。fork する方が適しているサービスにはどんなものがあるかを考えて実装してみよ。(C で書く場合は、課題で行なう stream.c の getstream を使うのが良い)アクセスカウンタを fork する server で作る場合には、lock 等が必要になる。lock を使う場合はWWWの演習で出て来る。また、アクセスカウンタ用のサーバを作ることにより、実現することもできる。lock と専用サーバの利点と欠点、向いているサービスなどについて考察せよ。
宿題(2) 定期的な実行
決まった時間で実行するには、setitimer というのを使う。signal が来るので、sigpause で待とう。
void check(void) { /* this function does nothing. */ } main() { .... struct itimerval itv ; int simt = 0, sent = 0, rect = 0 ; itv.it_interval.tv_sec = 0 ; itv.it_interval.tv_usec = TIMEDELTA * 1000 ; itv.it_value.tv_sec = 0 ; itv.it_value.tv_usec = TIMEDELTA * 1000 ; signal(SIGALRM, (void (*)(int))check) ; setitimer(ITIMER_REAL, &itv, NULL) ; for (;;) { sigpause(sigblock(0L)) ; do someting.... } }または、select のtimeout を使っても良い。(こちらの方が簡単か?)
どちらかの方法を使い、keyrecord に、途中で時間を表示するコードを足してみよう。
課題 (先週からの続き)
プロセスの同期 を来週までに行うこと。レポートはメールで
Subject: Report Operating System Lecture 11/21というように、課題を出した日付をサブジェクトに入れたメールで提出して下さい。