--------进程通讯 场景 父子进程通讯
https://wiki.swoole.com/wiki/page/214.html
<?php use SwooleProcess; echo "当前进程ID:".posix_getpid().PHP_EOL; //获取了进程ID cli_set_process_title("mymain"); //设置了进程名称 $child1=new Process(function(Process $p){ while(true){ sleep(1); $p->write("[进程1:12345]"); echo "进程1发送数据:[进程1:12345]".PHP_EOL; } },false,1,true); $child1->start(); $child2 = new Process(function(Process $p){ while(true){ // usleep(0.5*1000*1000); sleep(0.5); echo "进程2获取数据:".$p->read().PHP_EOL; } }); $child2->start(); while(true){ $child1_data = $child1->read(); $child2->write($child1_data); sleep(1); } Process::signal(SIGCHLD, function($sig) { //必须为false,非阻塞模式 while($ret = Process::wait(false)) { var_dump($ret); } });
[root@bogon swoole]# php7 ./poll.php 当前进程ID:2409 进程1发送数据:[进程1:12345] 进程2获取数据:[进程1:12345] 进程1发送数据:[进程1:12345] 进程2获取数据:[进程1:12345] 进程1发送数据:[进程1:12345] 进程2获取数据:[进程1:12345] 进程1发送数据:[进程1:12345] 进程2获取数据:[进程1:12345] 进程1发送数据:[进程1:12345] 进程2获取数据:[进程1:12345]
队列queue
<?php use SwooleProcess; echo "当前进程ID:".posix_getpid().PHP_EOL; //获取了进程ID cli_set_process_title("mymain"); //设置了进程名称 $child1=new Process(function(Process $p){ while(true){ sleep(3); for($i = 0 ;$i<=5;$i++){ $p->push($i); } } },false,1,true); $child1->useQueue(1,2); $child1->start(); $child2 = new Process(function(Process $p){ while(true){ sleep(0.5); echo "进程2获取数据:".$p->pop().PHP_EOL; } },false,1,true); $child2->useQueue(1); $child2->start(); $child3 = new Process(function(Process $p){ while(true){ sleep(0.5); echo "进程3获取数据:".$p->pop().PHP_EOL; } },false,1,true); $child3->useQueue(1); $child3->start(); Process::signal(SIGCHLD, function($sig) { //必须为false,非阻塞模式 while($ret = Process::wait(false)) { var_dump($ret); } });
[root@bogon swoole]# php7 ./poll.php 当前进程ID:2735 进程2获取数据:0 进程2获取数据:2 进程2获取数据:3 进程2获取数据:4 进程2获取数据:5 进程3获取数据:1 进程2获取数据:0 进程2获取数据:2 进程2获取数据:3 进程2获取数据:4 进程2获取数据:5 进程3获取数据:1 进程2获取数据:0 进程2获取数据:2 进程2获取数据:3 进程2获取数据:4 进程2获取数据:5 进程3获取数据:1 进程2获取数据:0 进程2获取数据:2 进程2获取数据:3 进程2获取数据:4 进程2获取数据:5 进程3获取数据:1
执行 外部程序
<?php require "vendor/autoload.php"; use SwooleProcess; use SwooleCoroutineMysql as MySQL; echo "当前进程ID:".posix_getpid().PHP_EOL; //获取了进程ID cli_set_process_title("mymain"); //设置了进程名称 $child1=new Process(function(Process $p){ $p->exec("/application/php7/bin/php",['./test.php']); },true,0,true); $child1->start(); while(true){ $ret=$child1->read(); echo $ret; usleep(0.5*1000*1000); } Process::signal(SIGCHLD, function($sig) { //必须为false,非阻塞模式 while($ret = Process::wait(false)) { //var_dump($ret); } });
crontab表达式
<?php date_default_timezone_set('PRC'); //设置中国时区 require_once 'vendor/autoload.php'; $config=[ "job1"=>[ "cron"=> CronCronExpression::factory('* * * * *'), "func"=>function(){ echo "job1".date("Y-m-d h:i").PHP_EOL; }, "current"=>date("Y-m-d H:i"), "nth"=>0 ] ]; while(true){ foreach($config as $key=>&$value){ $cron=$value["cron"]; $func=$value["func"]; $current=$value["current"]; $nth=$value['nth']; $time=$cron->getNextRunDate($value["current"],$nth,false)->getTimestamp()-strtotime(date("Y-m-d H:i")); if($time===0){ //执行业务逻辑 $func(); $value['nth']=$value['nth']+1; } } sleep(1); }
多进程创建任务并回收
<?php use SwooleProcess; cli_set_process_title("mymaster"); $manger = new Process(function(Process $process){ cli_set_process_title("mymanager"); while(true){ sleep(0.1); $process->write(json_encode(["a"=>123,"b"=>456])); Process::kill(posix_getppid(),SIGUSR1); } },false,1); $manger->start(); Process::signal(SIGUSR1, function($sig) use($manger) { $data[] = $manger->read(); $child=new Process(function(Process $process) use($data){ sleep(1); echo $data.PHP_EOL; }); $child->start(); }); Process::signal(SIGCHLD, function($sig) { //必须为false,非阻塞模式 while($ret = Process::wait(false)) { //var_dump($ret); } });
上述代码 无法会不断开启进程执行任务 需要新方案改进
swoole4.4.x之后子进程回收代码的问题处理: