この記事では、PHP デーモンの 2 つの一般的な実装方法を主に紹介し、具体的な例に基づいて PHP デーモンの原理、関連する実装方法、および運用上の注意事項を分析します。
最初の方法は、nohup と & を一緒に使用することです。コマンドの後にアンパサンドを追加すると、コンソールを占有することなく、開始されたプロセスをバックグラウンドで実行できます。 ここでは、while 無限ループを使用して説明します。
<?php while(true){ echo time().PHP_EOL; sleep(3); }
[root@localhost php]# php deadloop.php & [1] 3454 [root@localhost php]# ps aux | grep 3454 root 3454 0.0 0.8 284544 8452 pts/0 T 18:06 0:00 php deadloop.php root 3456 0.0 0.0 103316 896 pts/0 S+ 18:08 0:00 grep 3454 [1]+ Stopped php deadloop.php [root@localhost php]#
[root@localhost php]# fg php deadloop.php 1470996682 1470996685 1470996688 1470996691
SIGHUP は、次の 3 つの状況で、対応するプロセスに送信されます:
1. ターミナルが閉じられると、シグナルが送信されます。セッションの最初のプロセスとジョブとして送信されたプロセス (つまり、& 記号で送信されたプロセス)2. セッションの最初のプロセスが終了すると、セッション内のフォアグラウンド プロセス グループ内のすべてのプロセスにシグナルが送信されます。 3. 親プロセスが終了すると、そのプロセスグループが孤立プロセスグループで、プロセスグループ内のプロセスが停止した場合(SIGSTOP または SIGTSTP シグナルを受信した場合)、プロセスグループ内のすべてのプロセスにシグナルが送信されます。
1 と 2 を組み合わせると、プロセスが & (ジョブ モード) で開始されたかどうかに関係なく、端末を閉じるときに SIGHUP シグナルが受信されることがわかります。それでは、プロセスは SIGHUP シグナルを受信したときに何をしますか? Baidu Encyclopedia から引用した同じ文を参照してください
SIGHUP シグナルのシステムのデフォルトの処理は、シグナルを受信するプロセスを終了することです。したがって、プログラムでシグナルがキャプチャされていない場合、シグナルを受信した時点でプロセスは終了します。
<?php declare(ticks = 1); pcntl_signal(SIGHUP, function(){ // 这地方处理信号的方式我们只是简单的写入一句日志到文件中 file_put_contents('logs.txt', 'pid : ' . posix_getpid() . ' receive SIGHUP 信号' . PHP_EOL); }); while(true){ echo time().PHP_EOL; sleep(3); }
[root@localhost php]# nohup php deadloop.php
[root@localhost php]# ls cmd.sh deadloop.php getPhoto.php nohup.out pics [root@localhost php]# tail -f nohup.out 1470999772 1470999775 1470999778 1470999781 1470999784 1470999787 1470999790 1470999793 1470999796 1470999799 1470999802
[root@localhost ~]# ps -ef | grep 3554 root 3554 3497 0 19:09 pts/0 00:00:00 php deadloop.php root 3575 3557 0 19:10 pts/1 00:00:00 grep 3554 [root@localhost ~]# ps -ef | grep 3554 root 3554 1 0 19:09 ? 00:00:00 php deadloop.php root 3577 3557 0 19:10 pts/1 00:00:00 grep 3554 [root@localhost ~]#
結論:
したがって、nohup メソッドと & メソッドを組み合わせると、開始されたプロセスはコンソールを占有せず、コンソールが閉じられた後、プロセスに依存しません。 .1 になり、孤立プロセスになりますが、これはデーモン プロセスのメカニズムと非常によく似ています。[root@localhost php]# nohup php deadloop.php >logs.txt 2>error.txt & [1] 3612 [root@localhost php]# ps -ef |grep 3612 root 3612 3557 0 19:18 pts/1 00:00:00 php deadloop.php root 3617 3557 0 19:19 pts/1 00:00:00 grep 3612 [root@localhost php]#
から分離されていることです。実装されたコード。主要な箇所にコメントが含まれています。 <?php
$pid = pcntl_fork();
if ($pid == -1)
{
throw new Exception('fork子进程失败');
}
elseif ($pid > 0)
{
//父进程退出,子进程变成孤儿进程被1号进程收养,进程脱离终端
exit(0);
}
// 最重要的一步,让该进程脱离之前的会话,终端,进程组的控制
posix_setsid();
// 修改当前进程的工作目录,由于子进程会继承父进程的工作目录,修改工作目录以释放对父进程工作目录的占用。
chdir('/');
/*
* 通过上一步,我们创建了一个新的会话组长,进程组长,且脱离了终端,但是会话组长可以申请重新打开一个终端,为了避免
* 这种情况,我们再次创建一个子进程,并退出当前进程,这样运行的进程就不再是会话组长。
*/
$pid = pcntl_fork();
if ($pid == -1)
{
throw new Exception('fork子进程失败');
}
elseif ($pid > 0)
{
// 再一次退出父进程,子进程成为最终的守护进程
exit(0);
}
// 由于守护进程用不到标准输入输出,关闭标准输入,输出,错误输出描述符
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
/*
* 处理业务代码
*/
while(TRUE)
{
file_put_contents('log.txt', time().PHP_EOL, FILE_APPEND);
sleep(5);
}
Linux での PHP バックグラウンド デーモンの実装環境方法
以上がPHPデーモンの2つの方式を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。