PHP非阻塞实现方法
浏览:1358次 出处信息
为让 PHP 在后端处理长时间任务时不阻塞,快速响应页面请求,可以有如下措施:
1 使用 fastcgi_finish_request()
如果 PHP 与 Web 服务器使用了 PHP-FPM(FastCGI 进程管理器),那通过 fastcgi_finish_request() 函数能马上结束会话,而 PHP 线程可以继续在后台运行。
echo "program start..."; file_put_contents('log.txt','start-time:'.date('Y-m-d H:i:s'), FILE_APPEND); fastcgi_finish_request(); sleep(1); echo 'debug...'; file_put_contents('log.txt', 'start-proceed:'.date('Y-m-d H:i:s'), FILE_APPEND); sleep(10); file_put_contents('log.txt', 'end-time:'.date('Y-m-d H:i:s'), FILE_APPEND);
从输出结果可看到,页面打印完program start...
,输出第一行到 log.txt 后会话就返回了,所以后面的 debug...
不会在浏览器上显示,而 log.txt 文件能完整地接收到三个完成时间。
2 使用 fsockopen()
使用 fsockopen() 打开一个网络连接或者一个Unix套接字连接,再用 stream_set_blocking() 非阻塞模式请求:
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30); if (!$fp) { die('error fsockopen'); } // 转换到非阻塞模式 stream_set_blocking($fp, 0); $http = "GET /save.php / HTTP/1.1\r\n"; $http .= "Host: www.example.com\r\n"; $http .= "Connection: Close\r\n\r\n"; fwrite($fp, $http); fclose($fp);
3 使用 cURL
利用cURL中的 curl_multi_* 函数发送异步请求
$cmh = curl_multi_init(); $ch1 = curl_init(); curl_setopt($ch1, CURLOPT_URL, "http://localhost/"); curl_multi_add_handle($cmh, $ch1); curl_multi_exec($cmh, $active); echo "End\n";
4 使用 Gearman/Swoole 扩展
Gearman 是一个具有 php 扩展的分布式异步处理框架,能处理大批量异步任务。
Swoole 最近很火,有很多异步方法,使用简单。
5 使用缓存和队列
使用redis等缓存、队列,将数据写入缓存,使用后台计划任务实现数据异步处理。
这个方法在常见的大流量架构中应该很常见吧
6 调用系统命令
极端的情况下,可以调用系统命令,可以将数据传给后台任务执行,个人感觉不是很高效。
$cmd = 'nohup php ./processd.php $someVar >/dev/null &'; `$cmd`
7 使用 pcntl_fork()
安装 pcntl
扩展,使用 pcntl_fork() 生成子进程异步执行任务,个人觉得是最方便的,但也容易出现僵尸进程。
$pid = pcntl_fork() if ($pid == 0) { child_func(); //子进程函数,主进程运行 } else { father_func(); //主进程函数 } echo "Process " . getmypid() . " get to the end.\n"; function father_func() { echo "Father pid is " . getmypid() . "\n"; } function child_func() { sleep(6); echo "Child process exit pid is " . getmypid() . "\n"; exit(0); }
8 PHP 原生支持
外国佬的大招,没看懂
http://nikic.github.io/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html
来源:https://www.awaimai.com/660.html
建议继续学习:
- 关于IO的同步,异步,阻塞,非阻塞 (阅读:14487)
- Linux下访问文件的基本模式 (阅读:3107)
- MySQL在切换binlog时会阻塞更新 (阅读:2971)
- 总结一下遇到过的网络同步IO导致服务阻塞的问题 (阅读:2727)
- 用insert delayed减少阻塞时间 (阅读:2734)
- Linux 核心编程 – fsync, write (阅读:2512)
- 说说最近Google:safebrowsing引发页面加载阻塞的问题 (阅读:1175)
- 使用 Mojolicious 写非阻塞的应用: Part 1 (阅读:987)
- 使用 Mojolicious 写非阻塞的应用: Part 2 (阅读:866)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:通过Twemproxy提升PHP/Redis的性能
后一篇:深入理解PHP7内核之Reference >>
文章信息
- 作者:智足者富 来源: 陈鹏个人博客
- 标签: 阻塞 非阻塞
- 发布时间:2019-01-01 21:04:14
建议继续学习
近3天十大热文
- [46] 界面设计速成
- [40] 视觉调整-设计师 vs. 逻辑
- [40] Oracle MTS模式下 进程地址与会话信
- [38] IOS安全–浅谈关于IOS加固的几种方法
- [37] android 开发入门
- [36] 程序员技术练级攻略
- [36] 如何拿下简短的域名
- [35] 【社会化设计】自我(self)部分――欢迎区
- [35] 图书馆的世界纪录
- [32] 读书笔记-壹百度:百度十年千倍的29条法则