複数クライアントへの対応(課題4)

課題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
2014-09-30