Heim  >  Artikel  >  Datenbank  >  Zwei gängige Methoden zur Implementierung von Daemon-Prozessen in PHP

Zwei gängige Methoden zur Implementierung von Daemon-Prozessen in PHP

黄舟
黄舟Original
2017-09-08 15:12:481482Durchsuche

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(&#39;logs.txt&#39;, &#39;pid : &#39; . posix_getpid() . &#39; receive SIGHUP 信号&#39; . 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(&#39;fork子进程失败&#39;);
}
elseif ($pid > 0)
{
  //父进程退出,子进程变成孤儿进程被1号进程收养,进程脱离终端
  exit(0);
}
// 最重要的一步,让该进程脱离之前的会话,终端,进程组的控制
posix_setsid();
// 修改当前进程的工作目录,由于子进程会继承父进程的工作目录,修改工作目录以释放对父进程工作目录的占用。
chdir(&#39;/&#39;);
/*
 * 通过上一步,我们创建了一个新的会话组长,进程组长,且脱离了终端,但是会话组长可以申请重新打开一个终端,为了避免
 * 这种情况,我们再次创建一个子进程,并退出当前进程,这样运行的进程就不再是会话组长。
 */
$pid = pcntl_fork();
if ($pid == -1)
{
  throw new Exception(&#39;fork子进程失败&#39;);
}
elseif ($pid > 0)
{
  // 再一次退出父进程,子进程成为最终的守护进程
  exit(0);
}
// 由于守护进程用不到标准输入输出,关闭标准输入,输出,错误输出描述符
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
/*
 * 处理业务代码
 */
while(TRUE)
{
  file_put_contents(&#39;log.txt&#39;, 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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn