煮酒听雨
首页
PHP
MYSQL
WEB
Linux
关于本站
登陆
注册
PHP实现多进程并发编程(异步调用)popen()
编辑时间:2019-12-05
编辑:忘尘
阅读:566
因为PHP不支持多线程,使用异步调用的请求多个HTTP的方式达到了程序并行执行效果,但是注意的是请求的HTTP过多的话,会大大加大了系统的开销。这个时候我们就需要“异步执行”技术来执行代码,异步执行的特点是后台静默执行,用户无需等待代码的执行结果。 ####PHP执行popen函数来实现异步编程或并发进程(多进程并发编程) ```linux popen(command,mode) ``` 若出错,则返回 false。 popen() 函数打开进程文件指针,返回一个和 fopen() 所返回的相同的文件指针,只不过它是单向的(只能用于读或写)并且必须用 pclose() 来关闭。此指针可以用于 fgets(),fgetss() 和 fwrite()。 - command 必需。规定要执行的命令。 - mode 必需。规定连接模式。 可能的值: - r: 只读 - w: 只写 (打开并清空已有文件或创建一个新文件) >该函数会创建一个管道,所以不会对PHP造成阻塞。但异步是有条件的,需要在command后面加上`&`,表示后台执行,另外如果使用`fread()`来读取管道数据,将会造成进程`阻塞`。如果推到后台的进程太多,可能会导致服务器系统资源耗尽而崩溃,所以必须控制进程数量。 ```linux pclose(popen("php test.php &",'r')); ``` <hr> ####popen使用的一点注意事项 ``` [www@kolk51adpaqmwgzzfmez test] php -r '$fp = popen("sleep 10;","r"); echo "a"; $fp = popen("sleep 20","r"); echo "b";' #a ``` >发现,程序一开始执行这里只输出了`a`, 并没有输出`b`,说明`sleep 10;`执行了, `sleep 200;` 没有立即执行,10秒后输出`b`,此时主程序没有退出(总执行20秒) ``` [www@kolk51adpaqmwgzzfmez test]php -r '$fp1 = popen("sleep 10;","r"); echo "a"; $fp2 = popen("sleep 20","r"); echo "b";' #ab ``` >popen返回赋值不同变量`$fp1 $fp2`,发现`a`、`b`都输出了,说明两条命令都被调起执行了;同时,我们也发现,主进程并没有立即退出,而是在等待所有子进程执行完毕(总执行20秒); ``` [www@kolk51adpaqmwgzzfmez test]php -r '$fp1 = popen("sleep 10 &","r"); echo "a"; $fp2 = popen("sleep 20 &","r"); echo "b";' #ab ``` >如果使用 "&" 将启动的命令推倒后台,主进程也就不等待了。 ``` [www@kolk51adpaqmwgzzfmez test] php -r 'popen("sleep 10","r"); echo "a"; popen("sleep 20","r"); echo "b";' ``` >这里`a`没有立刻输出,等待了`10秒`后办输出`a`。继续等待`20秒`输出`b`,(总执行30秒 )。说明如果不将popen赋值给一个变量,则进程阻塞,如果使用 "&" 将启动的命令推倒后台,则亦不阻塞。 <hr> 若在需要获取子进程输出的数据时,可以在脚本结束时register_shutdown_function回调函数访问管道获取子进程输出的数据 register_shutdown_function()该函数是来注册一个会在PHP中止时执行的函数。 stream_get_contents() 该函数是对一个已经打开的资源流进行操作,并将其内容写入一个字符串返回。 示例: ``` function foo() { echo date('Y-m-d H:i:s')."\n"; echo shell_exec('php -r \'sleep(1); echo date("Y-m-d H:i:s")." by shell_exec:blocking\n";\''); //阻塞 $pipe1 = popen('php -r \'sleep(2); echo date("Y-m-d H:i:s")." by popen1:non-blocking\n";\'', 'r'); //非阻塞(管道) $pipe2 = popen('php -r \'sleep(1); echo date("Y-m-d H:i:s")." by popen2:non-blocking\n";\'', 'r'); //非阻塞(管道) echo date('Y-m-d H:i:s')."\n"; //事件驱动(脚本结束事件),异步回调 register_shutdown_function(function() use ($pipe1, $pipe2) { echo stream_get_contents($pipe1); //输出子进程返回的数据 echo stream_get_contents($pipe2); //输出子进程返回的数据 pclose($pipe1); pclose($pipe2); }); } foo(); //输出 2020-11-26 11:55:37 2020-11-26 11:55:38 by shell_exec:blocking 2020-11-26 11:55:38 2020-11-26 11:55:40 by popen1:non-blocking 2020-11-26 11:55:39 by popen2:non-blocking ``` register_shutdown_function()该函数是来注册一个会在PHP中止时执行的函数。 stream_get_contents() 该函数是对一个已经打开的资源流进行操作,并将其内容写入一个字符串返回。
来说两句吧
提交评论
最新评论
我的标签
函数
面试
REDIS
LNMP
验证
时间
JS
LINUX
CPA
常量
MYSQL
备份
微信
文件
压缩
优化
SVN
PHP
集合
数组
HTML
收藏
NGINX
配置
日志
性能
加密
下载
FORM
WEB
样式
SQL
表单
配置,面试,REDIS
编码
ARRAY
替换
截取
密码
版本
进程
定时
测试
事务
数据
权限
安全
防火墙
索引
设计模式
安全,面试
缓存
热文排行
LNMP状态管理命令
navicat for mysql 导入xlsx,
(置顶)开发中常用功能知识点笔记
(置顶)收藏优秀分享文章集合
PHP加密解密算法(Discuz!经典代码)
PHP 获取数组第一个元素或最后一个值
Nginx配置 nginx.conf 文件中常用配
MySQL错误日志 [Warning] IP ad
Redis持久化:快照(RDB)和AOF简解
浅析SQLmap
随机文章
友情链接
官方手册
thinkphp
php扩展
Linux命令
lnmp
PHP中文网
鸟哥Linux私房
Nginx中文文档
json格式化
Redis手册
composer中文文档
CentOS下载
流程图
VPN代理
菜鸟网
奇淼教程
首页
PHP
MYSQL
WEB
Linux
关于本站
登陆
注册