マルチスレッドサーバを作る

投稿日:2019年04月14日 17時55分22秒

以前からシングルスレッドでQUEUEを使ってマルチ化したサーバwizdLiveを作っていたが、ちょっと考える所があってスレッド化した。サーバの高速化にはepollなどを使って使用できるsocketにのみ配信する方法とスレッドによる方法があるが、epollで実装してみたところepollで待ち合わせするところで止まってしまう。当たり前の事なんだけど、結局シングルスレッドの高速化を本質的に突き詰めるとノンブロッキングモードを使う事が寄与する部分が限定的であるという結論に達した。
それならばノンブロッキングではなくて非同期I/Oを使えばいいんだけど、非同期I/Oというのが結局はスレッドで実装されているようだと分かった。ならば最初からスレッドで実装した方が早いんじゃね?というのが今回の動機。

基本としてノンブロッキングモードは送受信はするけども、現在送受信可能な分しか送信しないというもの。バッファが足りないなどの場合にはEAGAINのエラーを出して止まる。

非同期呼び出し(Asynchronous Call)はメソッドを呼び出した瞬間に呼び出し元に処理が戻ってくるような呼び出しのこと。非同期で呼び出されたメソッドは、環境によって処理されるタイミングが変わる。
20110407135041
この図で自分が作っていたのはSyncronous(同期)のNon-Blockingなわけだ。
しかし非同期Non-blockingは送信が完了したかどうかなどをコールバックされる必要があるわけで、制御は別途行わなくてはならない。なのでここを完全にthreadに任せるとそれなりの結果がでるだろうというわけだ。以前にもスレッドサーバは作ったのだがファイルI/Oに特化したもので、今回はCGIにも目を向けている。
これを突き詰めるとどれかのプロセスは暇になるので、なるべく暇な時間は寝ていてもらうプログラムがいいわけだ。そこで読み、書き、CGIのそれぞれが全力で動作しsocketへの書き込みや読み込み時にBLOCKされるようにした。この時間は内部的にはスレッドがスライスされる時間でポーリングされているだろう。

実際にやってみるとシングルスレッドで楽をした部分などでリエントラントになってない所も多くかなり書き換えた。
多少バグも残っているがとりあえず息も絶え絶えに動作するところまでできた。
コンパイル時の指定だけでシングルスレッドかマルチスレッドか切り替える事ができてまあ良かったかな。

[<< 「ですます」を「だである」に その2]

[恐怖のナポリタンからメディア・リテラシーを学ぶ >>]