1

私は次のようなcrontabを持っています:

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

0-59 * * * * /var/www/html/private/fivemin/zdaemon.php >> /dev/null &

できるだけシンプルですよね?

私がテストしているzdaemon.phpは次のとおりです。

#!/usr/bin/php
<?


while(true){
        sleep(1);
}

?>

実行するたびに、次のようにハングします。

root     15532  0.0  0.1 57228 1076 ?        Ss   19:09   0:00 crond
root     16681  0.0  0.1 72196 1428 ?        S    21:46   0:00 crond
root     16682  0.0  0.0     0    0 ?        Zs   21:46   0:00 [bash] <defunct>
root     16683  0.0  0.5 54800 5740 ?        S    21:46   0:00 /usr/bin/php /var/www/html/private/fivemin/zdaemon.php
root     16687  0.0  0.1 72196 1428 ?        S    21:47   0:00 crond
root     16688  0.0  0.0     0    0 ?        Zs   21:47   0:00 [bash] <defunct>
root     16689  0.0  0.5 54800 5740 ?        S    21:47   0:00 /usr/bin/php /var/www/html/private/fivemin/zdaemon.php

私はこれで一日中壁に頭をぶつけてきました。誰かがこれを見たことがありますか?何かアイデアはありますか?

これは参照先です:Init.dスクリプトがぶら下がっています

4

4 に答える 4

10

ゾンビプロセス自体は、必ずしも悪いことではありません。プロセスが終了し、プロセスがまだそのステータスを取得していないことを示します (またはwait()関連するシステム コールを使用)。

何が起こっているかは次のとおりです-開始するスクリプトのstderrcronに関心があるため(スクリプトが失敗した場合に電子メールで送信できるようにするため)、スクリプトのstderrを添付して終了するパイプを作成します(ファイル記述子2 )。次に、パイプの読み取り側で読み取りを行い、スクリプトが終了してeof (ゼロ バイト) を読み取るのを待ちます。次に、スクリプトの戻りステータスを取得します。cronread()

あなたの例では、生成されたデーモンはstderrファイル記述子を継承するため、中間シェルが終了する(そして機能しなくなる)と、パイプはデーモンによって開かれたままになります。したがって、決してeofcronを読み取らないため、戻りステータスを取得することはありません。

解決策は、デーモンのstderrが閉じていることを確認することです。これは次のようにして実現できます。

0-59 * * * * /var/www/html/private/fivemin/zdaemon.php >> /dev/null 2>&1 &

stdoutstderrの両方 を書き込みます/dev/null

于 2010-09-20T09:16:39.950 に答える
2

あなたの主な問題は、stderrがまだシェルに移動しているのに、子プロセス(phpプロセス)がスリープしているため、ゾンビプロセスが発生していることだと思います。これを試して:

0-59 * * * * /var/www/html/private/fivemin/zdaemon.php &> /dev/null &

それでもゾンビプロセスで問題が発生する場合は、nohupをご覧ください。

于 2010-09-20T03:00:56.997 に答える
2

crontab でプロセスをバックグラウンドで実行するのは奇妙に思えます。&行末の を削除してみてください。

于 2010-09-20T06:31:10.443 に答える
0

デーモンを作成する通常の方法は、子プロセスをforkして作業を実行し、エラーコード0で親プロセスを終了することです。ただし、これが問題であるかどうかはわかりません。

私はこれをphpで行っていませんが、pcntl_fork()を使用して通常のcの方法を模倣することができます。

于 2010-09-20T03:12:11.363 に答える