创建第一个子进程、获取子进程ID、回收子进程
https://wiki.swoole.com/wiki/page/p-process.html
echo "当前进程ID:".posix_getpid().PHP_EOL; //获取了进程ID cli_set_process_title("mymain"); //设置了进程名称 $child=new \Swoole\Process(function(\Swoole\Process $p){ echo "我是子进程,ID是“; }); $child_pid=$child->start(); while(true) //写个死循环,让进程不退出 { sleep(1); }
<?php echo "当前进程ID:".posix_getpid().PHP_EOL; //获取了进程ID cli_set_process_title("mymain"); //设置了进程名称 $child=new \Swoole\Process(function(){ cli_set_process_title("mychild"); //设置了进程名称 echo "我是一个子进程,ID=".posix_getpid().PHP_EOL; while(true) //写个死循环,让进程不退出 { sleep(1); } }); $child->start(); \Swoole\Process::wait(); while(true) //写个死循环,让进程不退出 { sleep(1); }
[root@bogon ~]# ps -ef|grep my root 1903 1707 0 15:05 pts/0 00:00:00 mymain root 1904 1903 0 15:05 pts/0 00:00:00 mychild root 1906 1804 0 15:05 pts/1 00:00:00 grep --color=auto my
wait函数式阻塞的 只有子进程结束才会往下执行
---------
重定向子进程标准输出
父进程获取子进程数据 初步。。。。。
<?php echo "当前进程ID:".posix_getpid().PHP_EOL; //获取了进程ID cli_set_process_title("mymain"); $child = new \Swoole\Process(function(){ cli_set_process_title("mychild"); echo "我是一个子进程,ID=".posix_getpid().PHP_EOL; while(true){ echo "my name is "; sleep(1) ; } },true); $child->start(); \Swoole\Process::wait(false); while(true){ echo $child->read()." sunlong".PHP_EOL; sleep(1); }
[root@bogon swoole]# php7 ./poll.php 当前进程ID:2576 我是一个子进程,ID=2577 my name is sunlong my name is sunlong my name is sunlong my name is sunlong my name is sunlong my name is sunlong ♥
多个子进程的问题: 僵尸进程
<?php use Swoole\Process; echo "当前进程ID:".posix_getpid().PHP_EOL; //获取了进程ID cli_set_process_title("mymain"); //设置了进程名称 $child1=new Process(function(){ cli_set_process_title("mychild1"); //设置了进程名称 while(true) //写个死循环,让进程不退出 sleep(1); }); $child1->start(); $child2=new Process(function(){ cli_set_process_title("mychild2"); //设置了进程名称 }); $child2->start(); Swoole\Process::wait();
由于child2子进程迅速推出 导致整个程序退出,child1 就变成了僵尸进程
[root@bogon swoole]# php7 ./poll.php 当前进程ID:3014 [root@bogon swoole]# [root@bogon ~]# ps -ef|grep my root 3015 1 0 16:57 pts/0 00:00:00 mychild1 root 3018 1804 0 16:57 pts/1 00:00:00 grep --color=auto my
正确退出方式应该像python的join一样 等待所有子进程都退出才行
修改:
<?php use Swoole\Process; echo "当前进程ID:".posix_getpid().PHP_EOL; //获取了进程ID cli_set_process_title("mymain"); //设置了进程名称 $child1=new Process(function(){ cli_set_process_title("mychild1"); //设置了进程名称 while(true) //写个死循环,让进程不退出 sleep(1); }); $child1->start(); $child2=new Process(function(){ cli_set_process_title("mychild2"); //设置了进程名称 }); $child2->start(); Swoole\Process::wait(); Swoole\Process::wait();
增加一个waitI()
此时mychild1会阻塞住 huang住
[root@bogon ~]# ps -ef|grep my root 3091 1707 1 17:01 pts/0 00:00:00 mymain root 3092 3091 0 17:01 pts/0 00:00:00 mychild1 root 3095 1804 0 17:01 pts/1 00:00:00 grep --color=auto my
正确姿势 用信号来设置异步信号监听
Process::signal(SIGCHLD, function($sig) { //必须为false,非阻塞模式 while($ret = Process::wait(false)) { var_dump($ret); } });
[root@bogon swoole]# php7 ./poll.php 当前进程ID:3115 array(3) { ["pid"]=> int(3117) ["code"]=> int(0) ["signal"]=> int(0) }
信号说明: https://wiki.swoole.com/wiki/page/158.html https://wiki.swoole.com/wiki/page/362.html
一个最简单的例子:我们按下键盘Ctrl+C,我们的进程就停止了。 这就是信号 信号是进程间通信机制中唯一的异步通信机制,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。进程之间可以互相通过系统调用kill发送软中断信号
----------------在子进程中运行httpserver 修改进程名称
<?php use Swoole\Process; echo "当前进程ID:".posix_getpid().PHP_EOL; //获取了进程ID cli_set_process_title("mymain"); //设置了进程名称 $child1=new Process(function(){ $http = new Swoole\Http\Server("0.0.0.0","80"); $http->set(["worker_num"=>1]); $http->on("request",function($req,$res){ $res->end("myhttp"); }); $http->on("start",function($server){ cli_set_process_title("mymaster"); //设置了进程名称 }); $http->on("managerstart",function($server){ cli_set_process_title("mymanager"); //设置了进程名称 }); $http->on("workerstart",function($server){ cli_set_process_title("myworker"); //设置了进程名称 }); $http->start(); }); $child1->start(); Process::signal(SIGCHLD, function($sig) { //必须为false,非阻塞模式 while($ret = Process::wait(false)) { var_dump($ret); } });
[root@bogon ~]# ps -ef |grep my root 1858 1695 0 15:57 pts/0 00:00:00 mymain root 1859 1858 4 15:57 pts/0 00:00:00 mymaster root 1860 1859 1 15:57 pts/0 00:00:00 mymanager root 1862 1860 0 15:57 pts/0 00:00:00 myworker root 1864 1749 0 15:57 pts/1 00:00:00 grep --color=auto my
--------监控文件变动 进程感知
----------------------------------mysql简易巡检监控
检查连接数
select count(*) from information_schema.processlist 线程检查 select * from information_schema.GLOBAL_STATUS where Variable_name like 'Thread%‘ Thread_cached:线程池中还有多少可以被复用的线程 Thread_connected:和show processlist一样 Thread_created:新创建的thread Thread_running:正在运行的连接(非sleep)
代码:

<?php require "vendor/autoload.php"; use Swoole\Process; use Swoole\Coroutine\Mysql as MySQL; echo "当前进程ID:".posix_getpid().PHP_EOL; //获取了进程ID cli_set_process_title("mymain"); //设置了进程名称 $child1=new Process(function(){ cli_set_process_title("mychild"); //设置了进程名称 $mysql=new MySQL(); $conn=$mysql->connect(['host' => '192.168.29.1', 'user' => 'shenyi', 'password' => '123123', 'database' => 'information_schema',]); $checkConnect="select 1"; $checkProcessCount="select count(*) from information_schema.processlist"; $checkThead="select * from information_schema.GLOBAL_STATUS where Variable_name like 'Thread%'"; while(true){ $checkResult[]=date('Y-m-d h:i:s'); try{ sleep(3); $mysql->query($checkConnect); $checkResult[]="检查连接正常"; $res=$mysql->query($checkProcessCount); $checkResult[]="当前连接数: ".$res[0]["c"]; $res=$mysql->query($checkThead); $checkResult[]="检查线程情况"; foreach ($res as $row){ foreach($row as $key=>$value){ $checkResult[]=$key.":".$value; } } $checkResult[]="-----------------------------------------------"; echo implode(PHP_EOL,$checkResult); }catch (Exception $exception){ echo $exception->getMessage().PHP_EOL; } } },false,0,true); $child1->start(); Process::signal(SIGCHLD, function($sig) { //必须为false,非阻塞模式 while($ret = Process::wait(false)) { //var_dump($ret); } });
本文来自博客园,作者:孙龙-程序员,转载请注明原文链接:https://www.cnblogs.com/sunlong88/p/11480846.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
2018-09-07 flask请求上下文