[PHP-users 25241] Re: cli をデーモンとして使用する際の注意
komura
komura @ ma9.seikyou.ne.jp
2005年 4月 2日 (土) 02:47:33 JST
komura です。
On Thu, 31 Mar 2005 17:23:28 +0900
Ryuzo KOSAKI <kosaki @ fip.fujitsu.com> wrote:
> >どうやら、子プロセスの終了時に、データベースへの接続を解放してしまい、
> >次の接続が失敗してエラーが発生するようです。
>
> fork()した場合、リソースも複製されるのでそれまでの接続が混乱
> してしまうことがあります(混乱というのはヘンですが、いい用語を
> 思い付かない)。
> ただ、子がDBMSと通信しているときに親は何もせず、子が終了する
> ときにmysql_close()のようなことをやらなければ、処理は続行でき
> るかもしれません。うまく行くときと行かないときの差はここにあ
> るのかも。
あまり深くは調べていませんので、間違っているかもしれませんが、
PHP のソースを変更せずに、子プロセスの終了時に DBMS との接続を
閉じないようにする方法はないような気がします。
PostgreSQL で試したところでは、持続的接続(pg_pconnect) を使用
しても、子プロセスの終了時に接続を閉じてしまうようです。
> socket通信を行なう典型的なサーバのプログラムだとこんな感じに
> やっています。
>
> while (TRUE) {
> $soc2 = stream_socket_accept($soc); //connect待ち
> // エラー処理省略
> $pid = pcntl_fork();
> if ($pid === -1) {
> die("pcntl_fork() error);
> }
> elseif ($pid) {
> // 親は新しいsocketをcloseして待ちに戻る
> fclose($soc2);
> continue;
> }
> else {
> fclose($soc);
> // $soc2に対する子プロセスのいろんな処理
> exit(0);
> }
> }
> // ※子プロセスの処理は pcntl_signal() のハンドラで
> // pcntl_waitpid()を実行
>
> この場合でも、$soc2のIDは増え続けるんですね。リソースは開放
> されていたとしても、ちょっと、キモチ悪い。
確かにそうなりますね。
socket 通信としては一般的ではないと思いますが、以下のように
子プロセスで接続を待つようにすると $soc2 の ID は増えないようです。
PHP 5.0.3 で確認しました。
少し試した感じでは大きな問題はなさそうでしたが、実用できるかどうか
は分かりません。
$sock = stream_socket_server( 'tcp://127.0.0.1:10000', $errno, $errstr );
while ( TRUE ) {
$pid = pcntl_fork();
if ( $pid === -1 ) {
exit;
}
else if ( $pid ) {
pcntl_wait( $status );
}
else {
$soc2 = stream_socket_accept( $sock );
// エラー処理
fclose( $sock );
var_dump( $soc2 );
fwrite( $soc2, date( 'Y/m/d H:i:s' ) . "\n" );
fclose( $soc2 );
exit( 0 );
}
}
--
komura <komura @ ma9.seikyou.ne.jp>
PHP-users メーリングリストの案内