Le contenu de cet article est de partager avec vous l'introduction de la programmation multi-processus et des processus orphelins et zombies dans la programmation système PHP. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer
. La programmation multi-processus est également un aspect important de la programmation système, mais les programmeurs PHP n'ont généralement pas besoin de se soucier des problèmes multi-processus, car le serveur Web ou PHP-FPM a déjà géré les problèmes de processus pour nous, mais si nous voulons utiliser PHP Lors du développement de programmes CLI, la programmation multi-processus est une technologie de base indispensable.
La méthode de contrôle de processus en PHP utilise principalement l'extension PCNTL (Process Control). Par conséquent, avant d'effectuer une programmation multi-processus, vous devez d'abord vous assurer que votre PHP dispose de la dernière version de PCNTL. Extensions, vous pouvez saisir la commande php -m pour afficher les extensions actuellement installées :
Cette extension nous fournit un ensemble de méthodes pour les opérations de processus :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
pcntl_fork — Génère une branche (enfant) à la position actuelle du processus actuel). Annotation : fork crée un processus enfant, un processus parent et un processus enfant Ils commencent tous à partir de la position fork et continuent vers le bas. La différence est que lors de l'exécution du processus parent, la valeur de retour fork obtenue est le numéro du processus enfant et le processus enfant obtient 0.
Le processus enfant dupliqué est presque une copie complète du processus parent. Les processus parent et enfant partagent des segments de code, bien que le segment de données, le tas et la pile. Les processus parent et enfant sont indépendants les uns des autres, mais au début, le processus enfant copie complètement les données du processus parent, mais les modifications ultérieures ne s'affectent pas.
1 |
|
Créer une démonstration de code de 5 sous-processus :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Exécuter le résultat :
1 2 3 4 5 6 7 |
|
Il est important de comprendre la fonction pcntl_fork : "fork crée un processus enfant, le parent Le processus et le processus enfant continuent de s'exécuter à partir de la position de fork. La différence est que pendant l'exécution du processus parent, la valeur de retour du fork est le numéro du processus enfant et le processus enfant obtient 0"
Modifiez légèrement le code ci-dessus pour empêcher le processus de se terminer, puis utilisez la commande ps pour vérifier l'état du système :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
Après l'exécution, entrez ps -ef grep php pour afficher le processus système
1 2 3 4 5 6 7 8 |
|
Vous pouvez voir 6 processus php process.php, la deuxième colonne est le processus et la troisième colonne est le processus parent du numéro de processus, vous pouvez voir que les numéros de processus parents des cinq processus suivants sont tous les numéros de processus du premier processus.
Le code ci-dessus, le processus enfant et le processus parent exécutent le même code. Existe-t-il un moyen de faire en sorte que le processus enfant et le processus parent. faire des choses différentes ? , le moyen le plus simple est de juger si le processus enfant exécute le code du processus enfant et si le processus parent exécute le code du processus parent :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
En fait, les processus parent et enfant du programme ci-dessus exécutent toujours le même code, mais les branches if les entrées sont différentes, et pcntl_exec peut complètement séparer le processus enfant de l'influence du processus parent, pour implémenter de nouvelles procédures.
pcntl_exec — 在当前进程空间执行指定程序
1 |
|
path
path必须时可执行二进制文件路径或一个在文件第一行指定了 一个可执行文件路径标头的脚本(比如文件第一行是#!/usr/local/bin/perl的perl脚本)。 更多的信息请查看您系统的execve(2)手册。
args
args是一个要传递给程序的参数的字符串数组。
envs
envs是一个要传递给程序作为环境变量的字符串数组。这个数组是 key => value格式的,key代表要传递的环境变量的名称,value代表该环境变量值。
注意该方法的返回值比较特殊:当发生错误时返回 FALSE ,没有错误时没有返回,因为pcntl_exec调用成功,子进程就去运行新的程序 从父进程继承的代码段、数据段、堆、栈等信息全部被替换成新的,此时的pcntl_exec函数调用栈已经不存在了,所以也就没有返回了。代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
运行结果:
1 2 3 4 5 6 7 8 9 10 |
|
以上就是对PHP多进程开发的简单介绍,对于子进程不同的存续状态,引出孤儿进程和僵尸进程的概念,在linux系统中,init进程(1号进程)是所有进程的祖先,其他进程要么是该进程的子进程,要么是子进程的子进程,子进程的子进程的子进程...,linux系统中可以用 pstree 命令查看进程树结构:
在多进程程序中,如果父进程先于子进程退出,那么子进程将会被init进程收养,成为init进程的子进程,这种进程被称为孤儿进程,我们可以把上面的代码稍作修改来演示这种情况:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
运行该程序,然后查看进程状态:
1 2 3 4 5 6 7 |
|
可以看到五个子进程的父进程号都是1了,并且这时控制台不再被程序占用,子进程转到了后台运行,这种孤儿进程被init进程收养的机制是实现后面将要介绍的守护进程的必要条件之一。
子进程还有一种状态叫僵尸进程,子进程结束时并不是完全退出,内核进程表中仍旧保有该进程的记录,这样做的目的是能够让父进程可以得知子进程的退出状态,以及子进程是自杀(调用exit或代码执行完毕)还是他杀(被信号终止),父进程可以调用pcntl_wait 或 pcntl_waitpid 方法来回收子进程(收尸),释放子进程占用的所有资源,并获得子进程的退出状态,如果父进程不做回收,则僵尸进程一直存在,如果这时父进程也退出了,则这些僵尸进程会被init进程接管并自动回收。
对于linux系统来说,一个长时间运行的多进程程序一定要回收子进程,因为系统的进程资源是有限的,僵尸进程会让系统的可用资源减少。
代码演示僵尸进程的产生:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
运行之后查看进程状态:
1 2 3 4 5 6 7 8 |
|
僵尸进程会用
PHP的pcntl扩展提供了两个回收子进程的方法供我们调用:
1 2 |
|
pcntl_wait函数挂起当前进程的执行直到一个子进程退出或接收到一个信号要求中断当前进程或调用一个信号处理函数。 如果一个子进程在调用此函数时已经退出(俗称僵尸进程),此函数立刻返回。子进程使用的所有系统资源将被释放。
关于wait在您系统上工作的详细规范请查看您系统的wait(2)手册。这个函数等同于以-1作为参数pid 的值并且没有options参数来调用pcntl_waitpid() 函数。
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
运行结果:
1 2 3 4 5 6 7 |
|
这里只是对PHP多进程编程做了基本的介绍,后面会结合 信号、进程间通信以及守护进程 做更进一步的介绍,欢迎大家关注后续文章。
PHP是世界上最好的语言 That's all :)
相关推荐:
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!