Unix の nohup コマンドの機能は、ファイルが書き込み可能でない場合、プログラムのすべての出力を現在のディレクトリの nohup.out ファイルに保存することです。ファイル内の <ユーザー ホーム ディレクトリ>/nohup.out に配置されます。したがって、このコマンドを使用すると、PHP をシェル スクリプトとして記述し、ターミナル ウィンドウが閉じているかどうかに関係なく、ループを使用してスクリプトを実行し続けることができます。
30秒ごとに時間を記録してファイルに書き込む機能を備えたPHPアプレットの作成をすぐに開始します
コードをコピーします コードは次のとおりです:
# vi for_ever.php
#! /local/php/ bin/php
define('ROOT', dirname(__FILE__).'/');
set_time_limit(0);
while (true) {
file_put_contents(ROOT.'for_ever.txt', date( 'Y-m-d H:i :s')."n", FILE_APPEND);
echo date('Y-m-d H:i:s'), 'OK!';
保存して終了し、for_ever.php ファイルに実行権限を与えます:
# chmod +x for_ever.php
バックグラウンドで実行させます:
# nohup /home/andy/for_ever.php.php &
忘れずにバックグラウンドで実行できるように、最後に & 記号を追加します。上記のコマンドを実行すると、次のプロンプトが表示されます:
[1] 5157
nohup: 'nohup.out' に出力を追加します
すべてのコマンド実行出力情報が表示されます。 nohup.out ファイルに配置します。
この時点で for_ever.php for_ever.txt と nohup.out を同じディレクトリで開いて、効果を確認できます。
さて、永遠に続くよ、どうやって終わらせる?
# ps
PID TTY TIME CMD
4247 pts/1 00:00:00 bash
5157 pts/1 00:00:00 for_ever.php
5265 pts/1 00:00:00 ps
# kill -9 5157
プロセス番号 5157 を見つけて強制終了すると、
[1]+ Killed nohup /home/andy/for_ever.php が表示されます
OK!
===================
多くのプロジェクトでは、crontab を通じて定期的に実行する必要がある同様のバックエンド スクリプトが多数存在する場合があります。たとえば、10 秒ごとにユーザーのステータスを確認します。スクリプトは次のとおりです:
@file: /php_scripts/scan_userstatus.php
コードをコピーします
コードは次のとおりです:
#!/usr/bin/env php -q $status = has_goaway (); if ($ status) { //done
}
?> 秒、スクリプトが実行されます。
短期間のうちにスクリプトのメモリ リソースが解放されず、新しいスクリプトが有効になっていることがわかりました。言い換えれば、新しいスクリプトは開始されますが、古いスクリプトによって占有されていたリソースは期待どおりに解放されていません。このようにして、時間の経過とともに多くのメモリ リソースが無駄になります。このスクリプトにいくつかの改良を加えました。改良点は次のとおりです:
@file: /php_scripts/scan_userstatus.php
コードをコピーします
コードは次のとおりです:
#/usr/bin/ env php -q
while ( 1) {
$status = has_goaway();
if ($status) {
//done } usleep(10000000) ?> crontab はもう必要ありません。次のコマンドでスクリプトを実行すると、同じ機能効果を実現できます#chmod +x /php_scripts/scan_userstatus.php
#nohup /php_scripts/scan_userstatus.php &
ここでは、& を使用してスクリプトをバックグラウンドで実行します。ターミナルセッションウィンドウが閉じられ、プロセスが強制終了されるのを防ぐために、 nohup コマンドを使用します。それでは、Unin/Linux デーモンと同じように、nohup コマンドを使用せずに実行する方法はあるのでしょうか?次に、デーモン関数について説明します。
デーモンとは何ですか? デーモンは通常、端末を制御しないバックグラウンド タスクとして考えられています。これには 3 つの特徴があります。バックグラウンドで実行されること、起動したプロセスから分離されること、端末を制御する必要がないことです。一般的に使用される実装方法は、fork() -> setsid() -> fork() です:
@file: /php_scripts/scan_userstatus.php
コードは次のとおりです。次のように:
#/usr /bin/env php -q
daemonize();
while (1) {
$status = has_goaway();
if ($status) {
//done
}
usleep (10000000);
} デーモン化 () {
$pid = pcntl_fork();
if ($pid === -1 ) {
return FALSE; if ($pid) { usleep(500) ; exit(); // 親を終了します chdir("/");
$sid = posix_setsid() {
return FALSE; pid = pcntl_fork();
if ($pid === -1) {
return FALSE; else if ($pid) {
exit(0);
if (定義済み) 'STDIN')) {
fclose(STDIN);
}
if (定義('STDOUT')){
fclose(STDOUT);
}
if (定義('STDERR')) {
fclose(STDERR);
}
}
?>
デーモン プロセス関数を実装した後、常駐プロセスを作成できるため、実行する必要があるのは 1 回だけです:
#/php_scripts/scan_userstatus.php
ここでの 2 つのより重要な PHP 関数は、pcntl_fork() と posix_setsid() です。プロセスをフォーク () することは、実行中のプロセスのコピーを作成することを意味し、そのコピーは子プロセスとみなされ、元のプロセスは親プロセスとみなされます。 fork() の実行後、fork() を開始したプロセスおよび端末コントロールから分離できます。これは、親プロセスが自由に終了できることも意味します。 pcntl_fork()の戻り値は、-1は実行失敗、0は子プロセスにあること、戻りのプロセスID番号は親プロセスにあることを示します。ここで、親プロセスを終了します。 etsid() を実行すると、まず新しいプロセスが新しいセッションの「リーダー」になり、最後にプロセスが端末を制御しなくなります。これは、デーモン プロセスになるための最も重要なステップでもあります。つまり、デーモン プロセスではなくなります。ターミナルが閉じられると強制的にプロセスが終了します。これは、中断できない常駐プロセスにとって重要なステップです。最後の fork() を実行します。このステップは必須ではありませんが、通常は制御端末が取得されないようにするために実行されます。 (O_NOCTTY フラグを使用せずに端末デバイスを直接開くと、制御端末が取得されます。)
その他の注意点:
1) chdir() は、デーモン プロセスを常に存在するディレクトリに配置します。常駐プロセスによってファイル システムのアンマウントが制限されることはありません。
2)umask() はファイル モードを設定し、最大許容制限までのマスクを作成します。デーモンが読み取りおよび書き込み権限を持つファイルを作成する必要がある場合、より厳格な権限を持つ継承されたマスクは逆の効果をもたらします。
3) fclose(STDIN)、fclose(STDOUT)、fclose(STDERR) は標準 I/O ストリームを閉じます。出力 (エコー) がある場合、デーモンは失敗することに注意してください。したがって、STDIN、STDOUT、および STDERR は通常、指定されたファイルにリダイレクトされます。
http://www.bkjia.com/PHPjc/323870.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/323870.html技術記事 Unix の nohup コマンドの機能は、ファイルが書き込み可能でない場合、プログラムのすべての出力を現在のディレクトリの nohup.out ファイルに保存することです。ユーザーのホームページに掲載されています...