こないだ作った簡易Webサーバーをマルチタスク化するよ。

元記事はこちら

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を返すだけなんで軽いです。

クライアント側

web

過去やったコードとは違い、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つのプログラムになっているので、本書のように関数ごとにプログラムをわけて短く見やすいプログラムにしてみたりといろいろとやれそうな事はありますが、とりあえずは先のクライアントごとにスレッドを作成する方法に進みます。

では次回に。

 

Similar Posts:


Leave a Reply

Your email address will not be published. Required fields are marked *