[Ursprung] Jeder kennt den Daemon-Prozess (Daemon) unter Linux/Unix, wie z. B. unser häufig verwendetes httpd, mysqld usw., bei dem es sich um Programme handelt, die im residenten Speicher ausgeführt werden, ähnlich wie Dienste unter Windows. Im Allgemeinen werden Daemon-Prozesse in C/C++ geschrieben, was bedeutet, dass der übergeordnete Prozess unter der aktuellen Shell beendet wird und im Hintergrund ausgeführt wird, um keine Ausgabeinformationen auf dem Terminal zu generieren Zum Schreiben von Protokolldateien werden Funktionen wie Syslog verwendet.
Wir wissen, dass PHP eine Skriptsprache ist und über die PHP-Skript-Engine ausgeführt wird. Daher ist es schwierig, einen Daemon-Prozess zu erstellen. Heute werden wir Unix/Linux-Befehle kombinieren, um die Funktion unseres Daemon-Prozesses zu realisieren.
[Prinzip] Die Funktion des Befehls nohup unter Unix besteht darin, den Befehl auszuführen, ohne aufzuhängen. Gleichzeitig legt nohup die gesamte Ausgabe des Programms in der Datei nohup.out im aktuellen Verzeichnis ab nicht beschreibbar, es wird in der Datei <Benutzer-Home-Verzeichnis> /nohup.out abgelegt. Nachdem wir diesen Befehl erhalten haben, schreibt unser PHP-Programm ein Shell-Skript und verwendet eine Schleife, um unser Skript weiterlaufen zu lassen. Dann kann unser PHP-Skript weiterlaufen, egal ob unser Terminalfenster geschlossen ist oder nicht. Wenn unser PHP-Prozess beendet wird oder unser Betriebssystem neu gestartet wird, wird er natürlich automatisch beendet.
[Funktion] Sie werden sich sicherlich fragen, welchen Nutzen es hat, unser PHP-Skript zu einem Daemon zu machen? Natürlich gibt es die typischste Funktion, die im Grunde die Funktion von Cron ersetzen kann. Beispielsweise können bestimmte Vorgänge, die wir regelmäßig ausführen müssen, ausgeführt werden, und Cron wird natürlich nicht mehr benötigt Server neu gestartet wird, gibt es keine Möglichkeit, allgemeine Unix-Server nicht so einfach neu zu starten. Darüber hinaus können wir auch eine einfache serverseitige Funktion erstellen, z. B. einen Server, der Telnet verwenden kann. Hehe, es kann in eine kleine Hintertür umgewandelt werden, aber die Implementierung ist etwas kompliziert.
[Übung] Beispiel 1: Dateien automatisch generieren Wir werden nun zwei Beispiele durchführen, um unsere obige Aussage zu beweisen. Die erste Möglichkeit besteht darin, alle dreißig Sekunden automatisch eine Datei zu generieren und diese für immer auszuführen.
Zunächst müssen Sie sicherstellen, dass das Betriebssystem Unix oder Linux ist, beispielsweise FreeBSD, Redhat, Fedora oder SUSE. Dann müssen wir sicherstellen, dass sich unsere PHP-Skript-Engine in /usr/local/php/bin/php befindet. Der spezifische Pfad kann entsprechend Ihrem tatsächlichen Pfad geschrieben werden. Wenn keine Skript-Engine vorhanden ist, installieren Sie sie bitte selbst.
Wenn das aktuelle Verzeichnis beispielsweise /home/heiyeluren/ ist, verwenden wir vi oder andere Editoren, um eine Datei namens php_daemon1.php zu schreiben:
$ vi php_daemon1.php
Schreiben Sie dann den folgenden Code:
#!/usr/local/php/bin/php
<?
set_time_limit(0);
while(1)
{
@fopen("test_".time().".txt","w");
Schlaf(30);
}
?>
Speichern und beenden Sie dann vi und erteilen Sie dann der Datei php_daemon1.php ausführbare Berechtigungen:
$ chmod +x /home/heiyeluren/php_daemon1.php
Lassen Sie dann unser Skript im Hintergrund laufen und führen Sie den folgenden Befehl aus:
$ nohup /home/heiyeluren/php_daemon1.php &
Denken Sie daran, am Ende das &-Symbol hinzuzufügen, damit es im Hintergrund ausgeführt werden kann. Nach der Ausführung des obigen Befehls erscheint die folgende Eingabeaufforderung:
[1] 82480
Anhängen der Ausgabe an nohup.out
Nach der Rückkehr zum Auto erscheint eine Shell-Eingabeaufforderung. Der obige Tipp bedeutet also, dass die Ausgabeinformationen aller Befehlsausführungen in der oben erwähnten Datei nohup.out abgelegt werden. Nachdem wir den obigen Befehl ausgeführt haben, sehen wir alle dreißig Sekunden weitere Dateien, die mit test_ beginnen, im aktuellen Verzeichnis, z. B. test_1139901144.txt test_1139901154.txt und andere Dateien, was beweist, dass unser Programm im Hintergrund ausgeführt wird.
Wie beenden wir also die Ausführung des Programms? Der beste Weg ist, das Betriebssystem neu zu starten. Das ist natürlich nicht ratsam. Wir können den Prozess mit dem Kill-Befehl beenden. Natürlich kennen wir die PID-Nummer des Prozesses ID. Sie können den Befehl ps verwenden, um das Eintreffen zu sehen.
$ps
PID TT STAT TIME-BEFEHL
82374 p3 Ss 0:00.14 -bash (bash)
82510 p3 S 0:00.06 /usr/local/php/bin/php /home/heiyeluren/php_daemon1.php
82528 p3 R+ 0:00,00 ps
Oben haben wir gesehen, dass die Prozess-ID unseres PHP 82510 ist, also führen wir den Kill-Befehl aus:
$ kill -9 82510
[1]+ Nohup /home/heiyeluren/php_daemon1.php getötet
Wenn Sie diese Eingabeaufforderung sehen, wissen Sie, dass der Prozess abgebrochen wurde. Wenn Sie erneut ps eingeben, werden Sie feststellen, dass er nicht mehr vorhanden ist:
$ps
PID TT STAT TIME-BEFEHL
82374 p3 Ss 0:00.17 -bash (bash)
82535 p3 R+ 0:00,00 ps
Wenn Sie den Prozess nicht direkt mit dem ps-Befehl sehen können, verwenden Sie die beiden kombinierten ps- und apos-Befehle, um ihn anzuzeigen, und Sie werden den Prozess auf jeden Fall sehen können.
Basierend auf dem obigen Prozess können Sie den Prozess erweitern, um Ihr eigenes Cron-Programm zu erstellen. Dies ist natürlich nur eine Möglichkeit. Beispiel 2: Serverseitiger Daemon . Es wird grob serverseitig simuliert und dann im Hintergrund ausgeführt, um den Effekt eines serverseitigen Daemons zu erzielen.
Fahren Sie in unserem Home-Verzeichnis fort: /home/heiyeluren und bearbeiten Sie die Datei php_daemon2.php:
$ vi php_daemon2.php
Geben Sie den folgenden Code ein (der Code stammt aus dem PHP-Handbuch, ich habe die Kommentare geändert):
#!/usr/local/php/bin/php
<?php
/* http://www.knowsky.com/php.asp-Einstellungen zeigen keine Fehler an*/
error_reporting(0);
/* Das Skript-Timeout ist unendlich*/
set_time_limit(0);
/* Festlöschung starten */
ob_implicit_flush();
/* Die IP dieser Maschine und die Ports, die geöffnet werden müssen */
$address = '192.168.0.1';
$port = 10000;
/* Einen Socket generieren */
if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) {
echo "socket_create() fehlgeschlagen: Grund: " . socket_strerror($sock) "n";
}
/* IP-Adresse und Port binden */
if (($ret = socket_bind($sock, $address, $port)) < 0) {
echo „socket_bind() failed: reason:“ socket_strerror($ret) „n“;
}
/* Monitor-Socket-Verbindung */
if (($ret = socket_listen($sock, 5)) < 0) {
echo „socket_listen() failed: reason:“ socket_strerror($ret) „n“;
}
/*Endlose Schleife zur Überwachung von Benutzerverbindungen*/
Tun {
if (($msgsock = socket_accept($sock)) < 0) {
echo "socket_accept() fehlgeschlagen: Grund: " . socket_strerror($msgsock) "n";
brechen;
}
/* Eingabeaufforderungsinformationen an verbundene Benutzer senden*/
$msg = „=========================================rn " .
„Willkommen beim PHP-Testserver. rnrn“.
„Zum Beenden geben Sie ‚quit‘ ein. rn“ .
„Um den Server herunterzufahren, geben Sie ‚shutdown‘ ein.rn“ .
„Um eine Hilfemeldung zu erhalten, geben Sie ‚help‘ ein.rn“ .
"=========================================rn" .
"php>";
socket_write($msgsock, $msg, strlen($msg));
Tun {
if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) {
echo „socket_read() failed: reason:“ socket_strerror($ret) „n“;
Pause 2;
}
if (!$buf = trim($buf)) {
weitermachen;
}
/*Schließen Sie die Client-Verbindung, wenn der Client den Quit-Befehl eingibt*/
if ($buf == 'quit') {
brechen;
}
/* Wenn der Client den Befehl zum Herunterfahren eingibt, werden sowohl der Server als auch der Client heruntergefahren*/
if ($buf == 'shutdown') {
socket_close($msgsock);
Pause 2;
}
/* Hilfeinformationen ausgeben, wenn der Client den Hilfebefehl eingibt*/
if ($buf == 'help') {
$msg = „PHP-Server-Hilfenachricht rnrn“.
„Zum Beenden geben Sie ‚quit‘ ein. rn“ .
„Um den Server herunterzufahren, geben Sie ‚shutdown‘ ein.rn“ .
„Um eine Hilfemeldung zu erhalten, geben Sie ‚help‘ ein.rn“ .
"php>";
socket_write($msgsock, $msg, strlen($msg));
weitermachen;
}
/*Eingabeaufforderung, wenn der Client-Eingabebefehl nicht existiert*/
$talkback = „PHP: unbekannter Befehl ‚$buf‘.rnphp>“;
socket_write($msgsock, $talkback, strlen($talkback));
echo „$bufn“;
} while (true);
socket_close($msgsock);
} while (true);
/* Socket-Verbindung schließen */
socket_close($sock);
?>
Speichern Sie den obigen Code und beenden Sie den Vorgang.
Der obige Code vervollständigt in etwa eine Funktion, die der Telnet-Serverseite ähnelt. Das heißt, wenn die Serverseite das Programm ausführt, kann der Client zur Kommunikation eine Verbindung zum 10000-Port des Servers herstellen.
Fügen Sie der Datei ausführbare Berechtigungen hinzu:
$ chmod +x /home/heiyeluren/php_daemon2.php
Führen Sie den Befehl auf dem Server aus:
$ nohup /home/heiyeluren/php_daemon2.php &
Es tritt in den Hintergrundbetrieb ein und wir gehen über das Windows-Client-Telnet nach oben:
C:>telnet 192.168.0.1 10000
Wenn Sie dazu aufgefordert werden:
Verbindung zu 192.168.0.188 wird hergestellt...Die Verbindung zum Host an Port 10000 kann nicht geöffnet werden: Wenn die Verbindung fehlschlägt, bedeutet dies, dass der Server nicht geöffnet ist oder das obige Programm nicht korrekt ausgeführt wird. Bitte überprüfen Sie, ob PHP über die Option „–enable“ verfügt -Sockets-Funktion. Wenn Sie dazu aufgefordert werden:
=========================================
Willkommen beim PHP-Testserver.
Um den Vorgang zu beenden, geben Sie „quit“ ein.
Um den Server herunterzufahren, geben Sie „shutdown“ ein.
Um eine Hilfemeldung zu erhalten, geben Sie „Hilfe“ ein.
=========================================
php>
Dies bedeutet, dass wir uns erfolgreich mit dem in PHP geschriebenen serverseitigen Daemon verbunden haben. Nach der Eingabeaufforderung php> können wir drei Befehle wie „help“, „quit“ und „shutdown“ ausführen. Wenn die Befehlseingabe nicht diese drei ist, wird Folgendes angezeigt:
php> asdf
PHP: unbekannter Befehl „asdf“.
Führen Sie den Befehl „help“ aus, um „help php> help“ zu erhalten
Hilfemeldung zum PHP-Server
Um den Vorgang zu beenden, geben Sie „quit“ ein.
Um den Server herunterzufahren, geben Sie „shutdown“ ein.
Um eine Hilfemeldung zu erhalten, geben Sie „Hilfe“ ein.
Diese Serverseite wird nicht eingeführt und kann von Ihnen selbst erweitert werden.
Das Beenden des Prozesses erfolgt ähnlich wie in Beispiel 1.
[Zusammenfassung] Durch die oben genannten Erkenntnisse wissen wir, dass PHP auch als Daemon-Prozess verwendet werden kann, wenn es gut gestaltet ist. Wir lernen hier jedoch nur und Sie können es selbst recherchieren und aktualisieren .
Dieser Artikel bezieht sich auf das PHP-Chinesisch-Handbuch. Das Lesen weiterer Handbücher wird für Sie von großem Nutzen sein.