创建第一个子进程、获取子进程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);
}
});
View Code