課題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