• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
孙龙 程序员
少时总觉为人易,华年方知立业难
博客园    首页    新随笔    联系   管理    订阅  订阅
swoole进程
swoole创建进程,进程间的通信

创建第一个子进程、获取子进程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

 

 

本文来自博客园,作者:孙龙-程序员,转载请注明原文链接:https://www.cnblogs.com/sunlong88/p/11480846.html

posted on 2019-09-07 14:57  孙龙-程序员  阅读(515)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3