[PHP]exec()直後にApacheを(reload|graceful|restart)したら不思議な結果になった

PHPのexec関数の挙動にのめりこんでいる@DQNEOです。こんにちわ。

前回の記事 [PHP]execでバックグラウンド実行するときの落とし穴に落ちた。 nohup!nohup! に続いて、
exec関数で外部コマンドを実行した直後にApacheを再起動(reload|graceful|restart)したらどうなるか、実験してみました。

結果は不思議なことになりました。

実験コード

まず外部コマンドを用意します。
sleep.sh
#!/bin/sh

for i in $(seq 1 20) ; do  date ; sleep 1; 
次に、それをexec()で呼び出すPHPコードを書きました。

フォアグラウンド実行、バックグラウンド実行、バックグラウンド+nohup実行の3通り試しました。
フォアグラウンド実行
<?php
exec("./sleep.sh > log.txt");
バックグラウンド実行
<?php
exec("./sleep.sh > log.txt &");
バックグラウンド+nohup実行
<?php
exec("nohup ./sleep.sh > log.txt &");
ブラウザから上記PHPスクリプトを実行して、直後にApacheの再起動をかけて、sleep.shのプロセスがどうなるかを観察しました。

Apache再起動は次の3つを試しました。

/etc/init.d/httpd restart
/etc/init.d/httpd reload
/etc/init.d/httpd graceful

実験結果

このようになりました。

○...外部コマンドが起動しつづけた
×...外部コマンドが停止した

 フォアグラウンドバックグラウンドnohup + バックグラウンド
restart×××
reload××
graceful
結果の解釈について

/etc/init.d/httpd restart は中身が stop & start なので、どのケースでも停止するのはうなづけます。
etc/init.d/httpd reload は中身が kill -HUPなので、nohupをつけない限りは停止するのもわかります。

よくわからないのがバックグラウンドかつgracefulのケースです。
バックグランドexecした後、httpdプロセスは次のリクエストを待っているはずなので、gracefulで即再起動されて外部コマンドが停止するかと思ったのですが、予想に反して停止しませんでした。

どなたか、このメカニズムがわかる人がいたら教えてください。
カテゴリ:

人気記事