ひとりアドベントカレンダー2015 第23日目 〜 PHPer でもソケットプログラミングしてみたい その2(多重化するぞ)

  • このエントリーをはてなブックマークに追加
  • Pocket

23日目です!!

今日はきのうのエコーサーバーの続きです。きのうのまとめで予告したとおりデーモン化と多重化をやってみたいと思います。デーモン化することでサーバーはバックグラウンドプロセスとして動作するようになります。また、多重化することで複数のクライアントを同時に処理できるようになります。よりサーバーらしくなりますよね。

はじめに、 今回書いたプログラムを貼ります:

https://gist.github.com/maple-nishiyama/1df91e1ea30da6f99840

デーモン化

これは21日目の PHPer でもデーモンになってみたいでやったとおりにデーモン化の手順を踏めばよいです。手順を以下の関数にまとめました:

 多重化

複数クライアントからの接続を同時に処理する多重化には一般に3つほど方法があるようです。

  1. シングルプロセス・シングルスレッドで select() や poll() を使う
  2. マルチプロセス化して子プロセスで処理する
  3. マルチスレッド化してワーカースレッドで処理する

これらを組み合わせて行う方法もあるようです。詳しくは参考書籍をご覧ください。

今回は2のマルチプロセス化する方法でやってみたいと思います。(本当はこのシリーズでマルチスレッドを紹介していたので3を使いたかったのですが、どうやら pthread 下ではソケットが上手く扱えないようで、断念しました:https://github.com/krakjoe/pthreads/issues/508

実装としては、クライアントからの接続を受け付けてメッセージソケットを作成したら、プロセスをフォークして子プロセスでメッセージループに入る、というようにします。フォークする部分のコードは以下のようになります:

 メッセージループ部分はきのうの記事とほぼ同じです。メイン関数から次のように起動します:

プロセスの状態を見てみる 

試しに起動して、2つのクライアントから接続してみます。このときサーバーのプロセスは以下のように3つできています:

multiserver

3番めのプロセスは親プロセスのIDが1ですね。つまり、init を親としています。これがサーバーの本体(親プロセス)です。残り2つは本体( = プロセスID 33527)を親としている子プロセスですね。マルチプロセスによる多重化は成功のようです。

まとめ

PHP で書いたエコーサーバーをデーモン化&マルチプロセスで多重化しました。これでよりサーバーらしいプログラムになりました。実用するには接続数上限やエラーハンドリング、シグナル処理などまだまだ必要な処理はありそうですが・・・。

参考

今回も Linux ネットワークプログラミングバイブル を参考にしました。

  • このエントリーをはてなブックマークに追加
  • Pocket

SNSでもご購読できます。

コメントを残す

*