[Origen] Todo el mundo conoce el proceso demonio (Daemon) en Linux / Unix, como nuestro httpd, mysqld, etc. de uso común, que son programas que se ejecutan en la memoria residente, similares a los servicios en Windows. Generalmente, los procesos demonio están escritos en C / C ++, que consiste en generar procesos secundarios a través de una bifurcación. Cuando se elimina el proceso principal en el shell actual, el proceso secundario se ejecutará en segundo plano para no generar información de salida en el terminal. , se utilizan funciones como syslog para escribir archivos de registro.
Sabemos que php es un lenguaje de secuencias de comandos y se ejecuta a través del motor de secuencias de comandos php, por lo que es problemático crear un proceso demonio. Hoy combinaremos comandos de Unix/Linux para realizar la función de nuestro proceso demonio.
[Principio] La función del comando nohup en Unix es ejecutar el comando sin colgar. Al mismo tiempo, nohup coloca toda la salida del programa en el archivo nohup.out en el directorio actual. no se puede escribir, se coloca en el archivo <directorio de inicio del usuario> /nohup.out. Entonces, después de tener este comando, nuestro programa php escribe un script de shell y usa un bucle para mantener nuestro script en ejecución. Luego, sin importar si nuestra ventana de terminal está cerrada o no, nuestro script php puede seguir ejecutándose. Por supuesto, cuando nuestro proceso php finaliza o se reinicia nuestro sistema operativo, finalizará naturalmente.
[Función] Definitivamente preguntarás, ¿de qué sirve convertir nuestro script php en un demonio? Por supuesto que existen, como la función más típica, que básicamente puede reemplazar la función de cron. Por ejemplo, ciertas operaciones que necesitamos realizar con regularidad se pueden realizar con esta función y, por supuesto, ya no es necesario. Después de reiniciar el servidor, no hay forma. Sin embargo, los servidores Unix generales no son tan fáciles de reiniciar. Además, también podemos crear una función simple del lado del servidor, como crear un servidor que pueda usar Telnet. Se puede convertir en una pequeña puerta trasera, pero la implementación es un poco complicada.
[Práctica] Ejemplo 1: Generar archivos automáticamente Ahora haremos dos ejemplos para probar nuestra afirmación anterior. En primer lugar, la primera es generar automáticamente un archivo cada treinta segundos y ejecutarlo para siempre.
En primer lugar, debes asegurarte de que el sistema operativo sea Unix o Linux, como FreeBSD, Redhat, Fedora o SUSE. Luego debemos asegurarnos de que nuestro motor de script php esté en /usr/local/php/bin/php. La ruta específica se puede escribir de acuerdo con su ruta real. Si no hay un motor de script, instálelo usted mismo.
Por ejemplo, si el directorio actual es /home/heiyeluren/, entonces usamos vi u otros editores para escribir un archivo llamado php_daemon1.php:
$vi php_daemon1.php
Luego escribe el siguiente código:
#!/usr/local/php/bin/php
<?
set_time_limit(0);
mientras(1)
{
@fopen("test_".time().".txt","w");
dormir(30);
}
?>
Luego guarde y salga de vi, y luego otorgue permisos ejecutables al archivo php_daemon1.php:
$ chmod +x /home/heiyeluren/php_daemon1.php
Luego deje que nuestro script se ejecute en segundo plano y ejecute el siguiente comando:
$ nohup /home/heiyeluren/php_daemon1.php &
Recuerde agregar el símbolo & al final para que pueda ejecutarse en segundo plano. Después de ejecutar el comando anterior, aparecerá el siguiente mensaje:
[1] 82480
agregando salida a nohup.out
Después de regresar al automóvil, aparecerá un mensaje de shell. Entonces, el consejo anterior significa que la información de salida de toda la ejecución de comandos se colocará en el archivo nohup.out, que se mencionó anteriormente. Luego, después de ejecutar el comando anterior, veremos más archivos que comiencen con test_ en el directorio actual cada treinta segundos, como: test_1139901144.txt test_1139901154.txt y otros archivos, lo que demuestra que nuestro programa se está ejecutando en segundo plano.
Entonces, ¿cómo terminamos la ejecución del programa? La mejor manera es reiniciar el sistema operativo Jaja, por supuesto, esto no es recomendable. Podemos usar el comando kill para finalizar el proceso. Antes de finalizar el proceso, naturalmente conocemos el número PID del proceso. ID. Puedes usar el comando ps para verlo llegar.
$ps
COMANDO DE TIEMPO DE ESTADO PID TT
82374 p3 Ss 0:00.14 -bash (golpe)
82510 p3 S 0:00.06 /usr/local/php/bin/php /home/heiyeluren/php_daemon1.php
82528 p3 R+ 0:00.00ps
Arriba hemos visto que el ID del proceso de nuestro php es: 82510, por lo que ejecutamos el comando kill:
$ matar -9 82510
[1]+ Nohup asesinado /home/heiyeluren/php_daemon1.php
Cuando vea este mensaje, sabrá que el proceso se ha cancelado. Si vuelve a pulsar, encontrará que desapareció:
$ps
COMANDO DE TIEMPO DE ESTADO PID TT
82374 p3 Ss 0:00.17 -bash (golpe)
82535 p3 R+ 0:00.00ps
Si no puede ver el proceso directamente con el comando ps, utilice los dos comandos combinados ps y apos para verlo y definitivamente podrá ver el proceso.
Según el proceso anterior, puede expandir el proceso para crear su propio programa cron, entonces no necesita cron. Por supuesto, esta es solo una forma: Ejemplo 2: demonio del lado del servidor. Se simula aproximadamente usando PHP en el lado del servidor y luego se ejecuta en segundo plano para lograr el efecto de Daemon en el lado del servidor.
Continúe en nuestro directorio de inicio: /home/heiyeluren y edite el archivo php_daemon2.php:
$vi php_daemon2.php
Introduce el siguiente código (el código es del manual de PHP, he modificado los comentarios):
#!/usr/local/php/bin/php
<?php
/* http://www.knowsky.com/php.asp la configuración no muestra ningún error*/
informe_error(0);
/* El tiempo de espera del script es infinito*/
set_time_limit(0);
/* Iniciar limpieza fija */
ob_implicit_flush();
/* La IP de esta máquina y los puertos que deben abrirse */
$dirección = '192.168.0.1';
$puerto = 10000;
/* Generar un socket */
si (($calcetín = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) {
echo "socket_create() falló: motivo: " . socket_strerror($sock) "n";
}
/* Vincular la dirección IP y el puerto */
if (($ret = socket_bind($calcetín, $dirección, $puerto)) < 0) {
echo “socket_bind() falló: motivo:” socket_strerror($ret) “n”;
}
/* Conexión del zócalo del monitor */
if (($ret = socket_listen($calcetín, 5)) < 0) {
echo “socket_listen() falló: motivo:” socket_strerror($ret) “n”;
}
/*Bucle indefinidamente para monitorear las conexiones de los usuarios*/
hacer {
si (($msgsock = socket_accept($calcetín)) < 0) {
echo "socket_accept() falló: motivo: " . socket_strerror($msgsock) "n";
romper;
}
/* Enviar información rápida a los usuarios conectados*/
$msg = “===========================================rn " .
"Bienvenido al servidor de pruebas PHP. rnrn".
"Para salir, escriba 'salir'. rn".
"Para apagar el servidor, escriba 'apagar'.rn".
"Para obtener un mensaje de ayuda, escriba 'ayuda'.rn".
"===========================================rn" .
"php>";
socket_write($msgsock, $msg, strlen($msg));
hacer {
si (falso === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) {
echo “socket_read() falló: motivo:” socket_strerror($ret) “n”;
romper 2;
}
si (!$buf = recortar($buf)) {
continuar;
}
/*Cierre la conexión del cliente cuando el cliente ingrese el comando de salida*/
si ($buf == 'salir') {
romper;
}
/* Cuando el cliente ingresa el comando de apagado, tanto el servidor como el cliente se apagan*/
si ($buf == 'apagar') {
socket_close($msgsock);
romper 2;
}
/* Genera información de ayuda cuando el cliente ingresa el comando de ayuda*/
si ($buf == 'ayuda') {
$msg = “Mensaje de ayuda del servidor PHP rnrn”.
"Para salir, escriba 'salir'. rn".
"Para apagar el servidor, escriba 'apagar'.rn".
"Para obtener un mensaje de ayuda, escriba 'ayuda'.rn".
"php>";
socket_write($msgsock, $msg, strlen($msg));
continuar;
}
/*Mensaje de aviso cuando el comando de entrada del cliente no existe*/
$talkback = “PHP: comando desconocido '$buf'.rnphp> “;
socket_write($msgsock, $talkback, strlen($talkback));
hacer eco “$bufn”;
} mientras (verdadero);
socket_close($msgsock);
} mientras (verdadero);
/* Cerrar conexión de socket */
socket_close($calcetín);
?>
Guarde el código anterior y salga.
El código anterior completa aproximadamente una función similar a la del lado del servidor Telnet, es decir, cuando el lado del servidor ejecuta el programa, el cliente puede conectarse al puerto 10000 del servidor para comunicarse.
Agregue permisos ejecutables al archivo:
$ chmod +x /home/heiyeluren/php_daemon2.php
Ejecute el comando en el servidor:
$ nohup /home/heiyeluren/php_daemon2.php &
Entra en funcionamiento en segundo plano, y subimos por el telnet del cliente de Windows:
C:>telnet192.168.0.1 10000
Si se le solicita:
Conectándose a 192.168.0.188... No se puede abrir la conexión al host en el puerto 10000: si la conexión falla, significa que el servidor no se abre o que el programa anterior no se ejecuta correctamente. Verifique si php tiene –enable. -Función de enchufes. Si se le solicita:
============================================
Bienvenido al servidor de prueba PHP.
Para salir, escriba "salir".
Para apagar el servidor, escriba "apagar".
Para recibir un mensaje de ayuda, escriba "ayuda".
============================================
PHP>
Esto significa que nos hemos conectado exitosamente al demonio del lado del servidor escrito en PHP. Después del indicador php>, podemos ejecutar tres comandos, como ayuda, salir y apagar. Si la entrada del comando no son estos tres, aparecerá el mensaje:
php>asdf
PHP: comando desconocido 'asdf'.
Ejecute el comando de ayuda para obtener ayuda php> ayuda
Mensaje de ayuda del servidor PHP
Para salir, escriba "salir".
Para apagar el servidor, escriba "apagar".
Para recibir un mensaje de ayuda, escriba "ayuda".
Este lado del servidor no se presentará y usted mismo puede ampliarlo.
Matar el proceso es similar al ejemplo 1.
[Resumen] A través del aprendizaje anterior, sabemos que PHP también se puede usar como un proceso demonio. Si está bien diseñado, la función será más poderosa. Sin embargo, recién estamos aprendiendo aquí y usted puede investigarlo y actualizarlo usted mismo. .
Este artículo hace referencia al manual chino de PHP. Leer más manuales le resultará muy beneficioso.