Dieser Artikel stellt hauptsächlich zwei gängige Implementierungsmethoden des PHP-Daemon-Prozesses vor. Er analysiert die Prinzipien des PHP-Daemon-Prozesses, zugehörige Implementierungsmethoden und Betriebsvorkehrungen in Form spezifischer Beispiele.
Die Beispiele in diesem Artikel beschreiben zwei gängige Implementierungsmethoden von PHP-Daemons. Teilen Sie es als Referenz mit allen. Die Details lauten wie folgt:
Die erste Möglichkeit besteht darin, nohup und & zusammen zu verwenden.
Fügen Sie nach dem Befehl das &-Symbol hinzu, damit der gestartete Prozess im Hintergrund ausgeführt werden kann, ohne die Konsole zu belegen. Hier verwende ich eine Endlosschleife wird zur Demonstration verwendet. Der Code lautet wie folgt:
<?php while(true){ echo time().PHP_EOL; sleep(3); }
Verwenden Sie die &-Methode, um den Prozess zu starten
[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]#
Sie können sehen, dass der Prozess die Konsole nicht belegt und die Konsole auch andere Befehle ausführen kann. Zu diesem Zeitpunkt können wir auch den Befehl fg verwenden, um den Prozess wieder in den normalen Konsolenbelegungsmodus zu versetzen.
[root@localhost php]# fg php deadloop.php 1470996682 1470996685 1470996688 1470996691
Das Obige ist eine kurze Einführung in den &-Befehl
Sehen wir uns einen weiteren Befehl nohup an
Fügen Sie nohup vor dem ein Befehl: Der gestartete Prozess ignoriert das Linux-Auflegesignal (SIGHUP). Unter welchen Umständen wird das SIGHUP-Signal unter Linux ausgelöst? Der folgende Inhalt stammt aus der Baidu-Enzyklopädie:
SIGHUP wird treten in den folgenden drei Situationen auf: Folgendes wird an den entsprechenden Prozess gesendet:
1 Wenn das Terminal geschlossen wird, wird das Signal an den Sitzungsersten Prozess gesendet und der Prozess als Job übermittelt (das ist der mit dem &-Symbol übermittelte Prozess)
2 . Wenn der erste Prozess der Sitzung beendet wird, wird dieses Signal an jeden Prozess in der Vordergrundprozessgruppe in der Sitzung gesendet
3. Wenn der übergeordnete Prozess beendet wird, Wenn die Prozessgruppe zu einer verwaisten Prozessgruppe wird und Prozesse in der Prozessgruppe gestoppt sind (SIGSTOP- oder SIGTSTP-Signal empfangen), wird das Signal an jeden Prozess in der Prozessgruppe gesendet.
Durch die Kombination von 1 und 2 wissen wir, dass das SIGHUP-Signal beim Schließen des Terminals empfangen wird, unabhängig davon, ob der Prozess im & (Job-Modus) gestartet wird. Wie wird der Prozess also mit dem SIGHUP-Signal umgehen? ? Siehe auch einen Satz aus der Enzyklopädie von Baidu
Die Standardverarbeitung des SIGHUP-Signals durch das System besteht darin, den Prozess zu beenden, der das Signal empfängt. Wenn das Signal daher nicht im Programm erfasst wird, wird der Prozess beendet, sobald das Signal empfangen wird.
Das heißt, beim Schließen des Terminalprozesses wird das SIGHUP-Signal empfangen, und die Standardverarbeitungsmethode dieses Signals besteht darin, den Prozess zu beenden. Natürlich können wir das Signal auch selbst verarbeiten oder ignorieren. Dies ist auch ein Beispiel für die obige Schleife. Wir haben sie leicht verbessert
<?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); }
Wir müssen nicht so mühsam sein, wir müssen nur den Befehl nohup verwenden Wird uns von Linux bereitgestellt, aber wenn wir Nohup verwenden, um den Prozess zu starten, schließen Sie ihn. Im Terminal ignoriert der Prozess das SIGHUP-Signal und wird nicht beendet. Entfernen Sie zunächst den Signalverarbeitungscode. Führen Sie dann nohup aus.
[root@localhost php]# nohup php deadloop.php
nohup: Ignorieren Sie die Eingabe und hängen Sie die Ausgabe an „nohup.out“ an
und nohup leitet die Ausgabe des Programms auf den aktuellen Stand von nohup um .out-Datei im Verzeichnis hat keine Schreibberechtigung, schreiben Sie $homepath/nohup.out
[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
Schließen Sie das Terminal zu diesem Zeitpunkt und der Vorgang wird nicht beendet. , wurde aber zu einem verwaisten Prozess (ppid=1), da der übergeordnete Prozess, der ihn erstellt hat, beendet wurde.
[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 ~]#
Fazit: Wenn wir also die Methoden nohup und & kombinieren, belegt der gestartete Prozess nicht die Konsole und ist nicht auf die Konsole angewiesen Nach dem Schließen der Konsole wird der Prozess von Prozess Nr. 1 übernommen und wird zu einem verwaisten Prozess. Dies ist dem Mechanismus eines Daemon-Prozesses sehr ähnlich.
[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]#
Wobei >logs.txt die Standardausgabe umleitet, leitet 2>error.txt die Standardfehlerausgabe um.
Das Obige ist eine Einführung in die erste Implementierungsmethode.
Die zweite Implementierungsmethode besteht darin, sie durch Code gemäß den Regeln und Merkmalen des Daemon-Prozesses zu implementieren , Das größte Merkmal des Daemon-Prozesses ist Es ist vom Benutzerterminal und der Sitzung getrennt. Im Folgenden finden Sie den implementierten Code und die wichtigsten Stellen werden kommentiert.
<?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); }
Das ist alles!
Das obige ist der detaillierte Inhalt vonZwei gängige Methoden zur Implementierung von Daemon-Prozessen in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!