Deux méthodes de processus démon en php

墨辰丷
Libérer: 2023-03-25 19:22:01
original
1665 Les gens l'ont consulté

Cet article présente principalement les deux méthodes démons en php. Les amis intéressés peuvent s'y référer. J'espère que cela pourra aider tout le monde.

La première façon est d'utiliser nohup et & ensemble.

L'ajout de l'esperluette après la commande permet au processus démarré de s'exécuter en arrière-plan sans occuper la console. La console peut également exécuter d'autres commandes. Ici, j'utilise une boucle infinie while pour démontrer. 🎜>

<?php

while(true){
        echo time().PHP_EOL;
        sleep(3);
}
Copier après la connexion

Utilisation et méthode pour démarrer le processus

[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]#
Copier après la connexion

Vous pouvez voir que le processus n'occupe pas la console et que la console peut également exécuter d'autres commandes , à ce stade, nous pouvons également utiliser la commande fg pour restaurer le processus en mode normal d'occupation de la console.



[root@localhost php]# fg
php deadloop.php
1470996682
1470996685
1470996688
1470996691
Copier après la connexion

Ce qui précède est une brève introduction à la commande &


Regardons une autre commande nohup

Ajoutez nohup avant la commande, le processus démarré ignorera le signal de blocage Linux (SIGHUP), donc dans quelles circonstances le signal SIGHUP sous Linux sera-t-il déclenché, comme suit Le contenu est extrait de l'Encyclopédie Baidu :


SIGHUP会在以下3种情况下被发送给相应的进程:
1、终端关闭时,该信号被发送到session首进程以及作为job提交的进程(即用 & 符号提交的进
程)
2、session首进程退出时,该信号被发送到该session中的前台进程组中的每一个进程
3、若父进程退出导致进程组成为孤儿进程组,且该进程组中有进程处于停止状态(收到SIGSTOP或
SIGTSTP信号),该信号会被发送到该进程组中的每一个进程。
Copier après la connexion

En combinant 1 et 2, nous savons que peu importe si le processus est démarré avec & (mode travail) , il sera collecté lors de la fermeture du terminal au signal SIGHUP, alors comment le processus gérera-t-il le signal SIGHUP ? Regardez la même phrase tirée de l'Encyclopédie Baidu

系统对SIGHUP信号的默认处理是终止收到该信号的进程。所以若程序中没有捕捉该信号,当收到该
信号时,进程就会退出。
Copier après la connexion
C'est-à-dire, fermer le signal SIGHUP ? Le processus terminal recevra le signal SIGHUP, et la valeur par défaut de ce signal est La façon de le gérer est de terminer le processus. Bien sûr, nous pouvons également capturer et gérer le signal nous-mêmes, ou l'ignorer par exemple. code suivant

<?php
pcntl_signal(SIGHUP, function(){
   //这地方处理信号的方式我们只是简单的写入一句日志到文件中
   file_put_contents(&#39;logs.txt&#39;, &#39;pid : &#39; . posix_getpid() . &#39; 
   receive SIGHUP 信号&#39; . PHP_EOL);
});
        
while(1) {
        sleep(10);
        pcntl_signal_dispatch();
}
Copier après la connexion
nous exécutons cette routine sur la ligne de commande puis fermons directement la fenêtre du terminal shell, puis rouvrons un terminal pour voir si le processus est toujours en cours :

<. 🎜> Vous pouvez voir que deadloop.php est toujours en cours d'exécution, et que son processus parent est devenu le processus init (car son processus parent d'origine est sorti et donc adopté par le processus init. D'après le contenu du fichier écrit, nous pouvons également voir). que le processus du terminal de fermeture a reçu le signal SIGHUP. En fait, nous n'avons pas besoin d'être aussi gênants, il suffit d'utiliser la commande nohup fournie par Linux. Cependant, lorsque nous utilisons nohup pour démarrer le processus, le processus ignorera le signal SIGHUP reçu et ne se terminera pas en premier. , supprimez le code de traitement du signal tout à l'heure. Ensuite, lancez nohup.
[root@localhost php]# ps -ef | grep deadloop.php 
root     16112     1  0 17:20 ?        00:00:00 php deadloop.php
root     16138 16115  0 17:24 pts/4    00:00:00 grep deadloop.php
[root@localhost php]# cat logs.txt 
pid : 16112 receive SIGHUP 信号
Copier après la connexion


[root@localhost php]# nohup php deadloop.php 
nohup: 忽略输入并把输出追加到"nohup.out"
Copier après la connexion


Et nohup redirigera la sortie du programme vers le fichier nohup.out dans le répertoire courant par défaut. il n'y a pas Si vous avez l'autorisation d'écriture, écrivez $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
Copier après la connexion
Si vous fermez le terminal à ce moment, le processus ne sera pas se terminera, mais deviendra un processus orphelin (ppid=1), car le processus parent qui l'a créé s'est arrêté.






[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 ~]#
Copier après la connexion



Conclusion : Ainsi, lorsque l'on combine les méthodes nohup et &, le processus démarré n'occupera pas la console et ne s'appuiera pas sur la console. Une fois la console fermée, le processus sera adopté par le processus n°1 et deviendra un processus orphelin. . C'est le même que le processus démon. Le mécanisme est très similaire.


[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]#
Copier après la connexion
Là où >logs.txt redirige la sortie standard, 2>error.txt redirige la sortie d'erreur standard.



Ce qui précède est une introduction à la première méthode de mise en œuvre.

La deuxième méthode d'implémentation consiste à l'implémenter via du code selon les règles et les caractéristiques du processus démon. La plus grande caractéristique du processus démon est qu'il est séparé du terminal utilisateur et de la session. code implémenté, avec des commentaires aux endroits clés.

<?php
$pid = pcntl_fork();
if ($pid == -1)
{
    throw new Exception(&#39;fork子进程失败&#39;);
}
elseif ($pid > 0)
{
    //父进程退出,子进程不是进程组长,以便接下来顺利创建新会话
    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);
}
Copier après la connexion


Recommandations associées :


Traitement du signal de processus PHP

PHP Explication détaillée de la communication inter-processus


Comment implémenter le verrouillage de processus PHP

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal