課題3のプログラムでは,サーバが同時に複数のクライアントに対応することがで きなかった.これでは,応答時間が遅くなるばかりか,正しい動作をしないクラ イアントによって,サーバが他のクライアントに全くサービスを提供できない状 態に陥いることもありえる.そこで,クライアントからの接続要求毎にプロセス を分けてサービスを行なえるようにサーバを変更する.
UNIX 系の OS ではforkシステムコールを用いてプロセスを生成することが
できる.fork システムコールは,プロセスが二つに分岐(fork) すること
で新しいプロセスを生成する.基本的には二つのプロセスは同じ働きをするもの
だが,アドレス空間は別になっており,親子関係がある.親プロセスは返り値と
して子プロセスのプロセスID を,子プロセスは返り値として 0 を受け取るので,
この返り値を用いて役割を割り当てることができる.
forkの典型的な使用例: int pid; for (;;) { ... pid = fork(); /* プロセスを親子に分岐 */ if (pid == 0) { /* 子プロセスでの処理 */ exit(0); } else { /* 親プロセスでの処理 */ } }この例では,forkシステムコールによってプロセスを親子に分岐する.そ れ以降の処理は親プロセス,子プロセスそれぞれで行なわれるが,pidの値 は,親子で異なるため,これを用いて条件分岐して親子の役割を分けることがで きる.
サーバプログラムはおおよそ以下のように変更される.
int pid, s, ns; .../* ソケット s を開き,bindし,listenで接続待ち */... for (;;) { ns = accept(s, ...); pid = fork(); /* プロセスを分岐 */ if (pid == 0) { /* 子プロセスでクライアントの要求を受け付ける */ close(listenfd); ... exit(0); } else { /* 親プロセスは次のクライアントからの接続を待つ */ close(acceptfd); } }
NAKAZAWA Koji