什么是进程
进程就是正在运行的程序的一个实例。
比如终端下运行一个PHP脚本,就是开启了一个进程,就会有一个对应的进程ID,即PID。
查看官方文档
创建一个SWOOLE
进程
在工作目录创建 process.php
<?php
$process = new swoole_process(function(swoole_process $process){
echo 111;
}, true);
$pid = $process->start();
echo $pid . PHP_EOL;
// 当结束的时候,回收结束运行的子进程
swoole_process::wait();
注意:进程和进程之间是通过管道进行通信的。在实例化swoole_process
的时候,传了第二个参数true
,这里觉得输出的内容不会打印到终端;如果设置为false
,这里可以打印到终端,这里不做演示。
进程 process.php
启动后,返回了进程ID,这里我们输出pid可以查看
[zhengzongqiang@localhost process]$ pwd
/opt/work/htdocs/swoole_mooc/demo/process
[zhengzongqiang@localhost process]$ php process.php
39388
创建一个HTTP
子进程
在process
进程开启一个http
子进程,修改 process.php
文件
$process = new swoole_process(function(swoole_process $process){
// 这里必须写php的绝对安装路径. /
$process->exec("/opt/soft/php/bin/php", [__DIR__.'/../server/http.php']);
}, true);
$pid = $process->start();
echo $pid . PHP_EOL;
// 当结束的时候,回收结束运行的子进程
swoole_process::wait();
运行程序,会打印该swoole_process
进程的进程ID,即39658
[zhengzongqiang@localhost process]$ php process.php
39658
接下来我们在新的会话中通过查看端口验证http
子进程是否开启
[root@localhost zhengzongqiang]# netstat -anp | grep 8811
tcp 0 0 0.0.0.0:8811 0.0.0.0:* LISTEN 39658/php
可以看到,我们之前配置的http
服务端口已经被监听,父进程ID为39658
,即swoole_process
进程开启了http
进程。
进程关系
进程开启之后,可以通过命令跟进进程之间的关系。
// ps aux | grep process.php
[zhengzongqiang@localhost ~]$ ps aux | grep process.php
zhengzo+ 39657 0.0 0.8 161496 8412 pts/1 S+ 00:54 0:00 /opt/soft/php/bin/php process.php
zhengzo+ 39973 0.0 0.0 112720 980 pts/2 R+ 01:03 0:00 grep --color=auto process.php
可以查看到两条进程,下边一个代表运行本命令的进程,39657
即运行process.php
的程序的进程ID,即39658
的父进程,即39657
进程开启了进程ID为39658
的swool_process进程,即39657
就是php process.php这条命令的进程ID。
查看进程树
通过以下命令可查看进程之间的关系
// pstree -p 39657
[zhengzongqiang@localhost ~]$ pstree -p 39657
php(39657)───php(39658)─┬─php(39659)───php(39661)
└─{php}(39660)
还可以通过以下命令查看进程的对应程序
// ps aft | grep http
[zhengzongqiang@localhost ~]$ ps aft | grep http
40193 pts/2 S+ 0:00 \_ grep --color=auto http
39658 pts/1 Sl+ 0:00 \_ /opt/soft/php/bin/php /opt/work/htdocs/swoole_mooc/demo/process/../server/http.php
39659 pts/1 S+ 0:00 \_ /opt/soft/php/bin/php /opt/work/htdocs/swoole_mooc/demo/process/../server/http.php
39661 pts/1 S+ 0:00 \_ /opt/soft/php/bin/php /opt/work/htdocs/swoole_mooc/demo/process/../server/http.php
我们可以看到,http
进程ID为39659
,其父进程ID为39658
进程,即swoole_process
进程,再父进程就是启动swoole_process
进程的进程,即执行此文件的的命令的进程,即39657
进程。
39659
进程也有子进程,即worker进程。
可以理解为39658
进程为master进程,39659
进程为manager进程。
SWOOLE 进程使用场景
有执行多个URL,需要获取这鞋URL地址中的内容,然后把它记录到相应的库里。
传统PHP的做法是同步顺序的执行这些URL,这个时候就会面另一个问题:
访问每隔URL地址都会有耗时,积少成多,这样会导致最后的响应时间太长,非常不友好。
这个问题可以通过引入swoole process
来解决,按需开启N个子进程,每个子进程去执行相应的URL,这样可以大大地缩短响应时间。
之前是一个主进程执行这些URl,引入swoole process
后,这个主进程可以开多个子进程,这样每一个子进程去执行一个URl,时间就会大大缩短。
SWOOLE - DEMO
创建curl.php
// 传统实现方式
$urls = [
'http://baidu.com',
'http://sina.com.cn',
'http://qq.com',
'http://baidu.com',
'http://sina.com.cn',
'http://qq.com'
];
foreach($urls as $url){
$content[] = file_get_contents($url);
}
这样,如果每请求一个地址花费1s时间;那么总共要花费6s。
通过swoole_process
实现
<?php
echo "process-start-time:".date('Y-m-d H:i:s').PHP_EOL;
$workers = [];
$urls = [
'http://baidu.com',
'http://sina.com.cn',
'http://qq.com',
'http://baidu.com',
'http://sina.com.cn',
'http://qq.com'
];
for($i = 0; $i < 6; $i++)
{
// 子进程
$process = new swoole_process(function(swoole_process $worker) use ($i, $urls){
$content = curlData($urls[$i]);
echo $content.PHP_EOL;
},true);
$pid = $process->start();
$workers[$pid] = $process;
}
foreach($workers as $worker){
echo $worker->read();
}
function curlData($url)
{
sleep(1);
return $url . 'success' . PHP_EOL ;
}
echo "process-end-time:" . date('Y-m-d H:i:s').PHP_EOL;
执行程序发现只用了1s
[zhengzongqiang@localhost process]$ php curl.php
process-start-time:2019-06-04 17:46:28
http://baidu.comsuccess
http://sina.com.cnsuccess
http://qq.comsuccess
http://baidu.comsuccess
http://sina.com.cnsuccess
http://qq.comsuccess
process-end-time:2019-06-04 17:46:29
注意:swoole
构造函数将内容输出到管道,还有另一种方式
$worker->write($content.PHP_EOL);