元記事はこちら
TCPEchoサーバーから超簡易TCPwebサーバーを作ってみた。
TCP/IP Socket in Cはひととおり最後まで終わったので、メインディッシュに置いておいた5章のマルチタスクのところになります。
本書ではマルチタスク化について、クライアントごとにプロセスを作成する方法、スレッドを作成する方法、制限付きマルチタスクという3つの方法を検証しています。
今回は
クライアントごとにプロセスを作成する方法
をやってみます。と言うても、forkする方法は以前にもやったことあるのと、サブルーチンはそのままで、Main関数のループ部分を本書を参照してクライアントの処理を子プロセスに行わせる処理に書き換えればそれで完了ですた。
てなわけでソースを公開してもつまらないので、動作がどうなったのかを載せていきたいと思います。
まずはサーバー側は
# ./TCPWebServer_type_Fork 8000 Handling client 192.168.24.53 with child process: 33102 GET /index.html HTTP/1.1Host: 192.168.24.61:8000 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-us;q=0.7,en;q=0.3Accept-Encoding: gzip, deflateCookie: _ga=GA1.4.2104063878.1399427134Connection: keep-aliveCache-Control: max-age=0 Handling client 192.168.24.53 with child process: 33163 GET /index.html HTTP/1.1Host: 192.168.24.61:8000 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-us;q=0.7,en;q=0.3Accept-Encoding: gzip, deflateCookie: _ga=GA1.4.2104063878.1399427134Connection: keep-aliveCache-Control: max-age=0
こんな感じになります。8000番で立ち上げていて、子プロセスのPIDが出力されています。本書のコードがこうなってます。GETが来たらhtmlを返すだけなんで軽いです。
クライアント側
過去やったコードとは違い、MaxClientが実装されていないので、今回は挙動がかなり違いますのお。
前回の参考サイト
yoshifumi1975’s diary
意図して、子プロセスの終了処理をしないコードにしてみました。
F5連打してみたら、こんな風にどんどん子プロセスが増えます。あらやだー。
1 0 3676 1615 20 0 0 0 exit Z+ pts/3 0:00 [TCPWebServer_ty] <defunct> 1 0 3677 1615 20 0 0 0 exit Z+ pts/3 0:00 [TCPWebServer_ty] <defunct> 1 0 3678 1615 20 0 0 0 exit Z+ pts/3 0:00 [TCPWebServer_ty] <defunct> 1 0 3679 1615 20 0 0 0 exit Z+ pts/3 0:00 [TCPWebServer_ty] <defunct> 1 0 3680 1615 20 0 0 0 exit Z+ pts/3 0:00 [TCPWebServer_ty] <defunct> 1 0 3681 1615 20 0 0 0 exit Z+ pts/3 0:00 [TCPWebServer_ty] <defunct> 1 0 3683 1615 20 0 0 0 exit Z+ pts/3 0:00 [TCPWebServer_ty] <defunct> 1 0 3684 1615 20 0 0 0 exit Z+ pts/3 0:00 [TCPWebServer_ty] <defunct> 1 0 3685 1615 20 0 0 0 exit Z+ pts/3 0:00 [TCPWebServer_ty] <defunct> [root@testserver_centos ~]# ps aux | grep TCPWeb | wc -l 383
本書の本来のコードだとちゃんと回収され増殖はしないようになってます。
[root@testserver_centos ~]# ps alx | grep TCPWeb 0 0 33071 4139 20 0 3928 488 inet_c S+ pts/3 0:00 ./TCPWebServer_type_Fork 8000 1 0 62130 33071 20 0 0 0 exit Z+ pts/3 0:00 [TCPWebServer_ty] <defunct>
前回はシグナルが理解できずにpkillでプロセスを落とすようなスクリプトを使っていましたが、今回はそもそもゾンビ化しません。
root@testserver_centos ~]# ps alx | grep TCPWeb 4 0 19396 42682 20 0 3928 488 inet_c S+ pts/3 0:00 ./TCPWebServer_type_Fork 800 1 0 19487 19396 20 0 0 0 exit Z+ pts/3 0:00 [TCPWebServer_ty] <defunct> 1 0 19518 19396 20 0 0 0 exit Z+ pts/3 0:00 [TCPWebServer_ty] <defunct> 1 0 19549 19396 20 0 0 0 exit Z+ pts/3 0:00 [TCPWebServer_ty] <defunct> 1 0 19550 19396 20 0 0 0 exit Z+ pts/3 0:00 [TCPWebServer_ty] <defunct> 1 0 19551 19396 20 0 0 0 exit Z+ pts/3 0:00 [TCPWebServer_ty] <defunct> 1 0 19582 19396 20 0 0 0 exit Z+ pts/3 0:00 [TCPWebServer_ty] <defunct> 1 0 19583 19396 20 0 0 0 exit Z+ pts/3 0:00 [TCPWebServer_ty] <defunct> 0 0 19885 22264 20 0 107456 944 pipe_w S+ pts/4 0:00 grep TCPWeb [root@testserver_centos ~]# kill 19396 [root@testserver_centos ~]# [root@testserver_centos ~]# ps alx | grep TCPWeb 0 0 20187 22264 20 0 107456 944 pipe_w S+ pts/4 0:00 grep TCPWeb [root@testserver_centos ~]#
今回の挙動とコードを参考にしつつ、前回参照させていただいたYoshifumiさんのコードを参照すればさらに理解が深まるかもしれません。
こんな感じです。
あとは余裕があればMaxClientの実装をしてしたり、今はながーい1つのプログラムになっているので、本書のように関数ごとにプログラムをわけて短く見やすいプログラムにしてみたりといろいろとやれそうな事はありますが、とりあえずは先のクライアントごとにスレッドを作成する方法に進みます。
では次回に。