Brief introduction
Swoole_process is a process management module provided by Swoole to replace the pcntl extension of PHP.
First, make sure that the Swoole version of the installation is greater than 1.7.2:
php --ri swooleswooleswoole support => enabledVersion => 1.10.1
Example description
In this case, three shell commands are consumed, and a sub-process is created to consume them. Spend 1 seconds of sleep deliberately to see the effect visually.
process_t1.php
<?php$start _time=Microtime(TRUE);$cmds=[ "Uname", "Date", "WhoAmI"];foreach ($cmds as $cmd){$process=NewSwoole_process( "My_process", true); $process->start(); $process->write($cmd); //Send data to child process via pipeline Echo $rec=$process->read();//Synchronous blocking read pipeline data}//Sub-processfunctionMy_process(Swoole_process$worker){Sleep(1);//intentionally suspended 1s $cmd=$worker->read(); //$return = EXEC ($cmd);//exec outputs only the last line of the command execution result, and requires an explicit print output Ob_start(); PassThru($cmd);//Execute external program and display unprocessed, raw output, print output directly. $return=Ob_get_clean(); if(!$return) $return=' null '; $worker->write($return);//Read and return data by pipe, or use echo instead of write //Echo exec ($return);//Read and return data by pipe}//Child process end must be performed wait to recycle or the child process will become a zombie process while($ret= Swoole_process::wait()){//$ret is the number group code is the process exit status code, $pid=$ret[' pid ']; Echo Php_eol."Worker Exit, pid=".$pid.Php_eol;}$end _time=Microtime(TRUE);Echo sprintf("Use time:%.3f s\ n", $end _time-$start _time);
Run on the command line:
php process_t1.php LinuxSat Apr 21 15:29:55 CST 2018rootWorker Exit, PID=672Worker Exit, PID=674Worker Exit, PID=676use time:3.080 s
Everyone will feel very strange, why open three sub-process, or use 3 seconds, it should be about 1 seconds or so.
The reason is that when the parent process reads the data returned by the child process, it is synchronous blocking reads:
echo$rec$process->read();//同步阻塞读取管道数据
The result is that the parent process waits for each process to finish processing and returns content before going to the next loop.
Solution 1:
Use the swoole_event_add
join pipeline to the event loop to become asynchronous mode:
// echo $rec = $process->read();//同步阻塞读取管道数据//使用swoole_event_add将管道加入到事件循环中,变为异步模式swoole_event_add($process->pipe,function($pipe)use($process) { echo$rec$process->read(); swoole_event_del($process->pipe);//socket处理完成后,从epoll事件中移除管道});
Execution Result:
Worker Exit, PID=686Worker Exit, PID=687Worker Exit, PID=688use time:1.060 sLinuxSat Apr 21 15:37:14 CST 2018root
You will find that the use time data is not printed last. It's already asynchronous. The actual execution time is around 1s.
Solution 2:
The return value of the child process is not fetched first, and returns uniformly after the loop is completed:
foreach ($cmds as $cmd){$process=NewSwoole_process( "My_process", true); $process->start(); $process->write($cmd); //Send data to child process via pipeline $process _arr[]=$process;}foreach ($process _arr as $process){Echo $rec=$process->read();}
Execution Result:
LinuxSat Apr 21 15:52:24 CST 2018rootWorker Exit, PID=694Worker Exit, PID=693Worker Exit, PID=695use time:1.061 s
Reference
1. Process
Https://wiki.swoole.com/wiki/page/p-process.html
2, Swoole_process->read
Https://wiki.swoole.com/wiki/page/217.html
Swoole_proces Implementing multiple Processes