PHP 异步执行方法,模拟多线程的应用分析


Posted in PHP onJune 03, 2013

PHP 本身没有多线程的东西,但可以曲线的办法来造就出同样的效果,比如多进程的方式来达到异步调用,只限于命令模式。
另外还有一种更简单的方式可用于 Web 程序中,那就是用 fsockopen()、fputs() 来请求一个 URL, 而无需等待返回,如果你在那个被请求的页面(URL)中做些事情就相当于异步了。
关键代码如下:

<?php
  $fp = fsockopen('localhost',80,&$errno,&$errstr,5);  
  if(!$fp)
     {
         echo "$errstr ($errno)<br />/n"; 
     }
     fputs($fp,"GET another_page.php?flag=1/r/n"); 
     fclose($fp);

上面的代码向页面 another_page.php 发送完请求就不管了,用不着等待请求页面的响应数据,利用这一点就可以在被请求的页面 another_page.php 中异步的做些事情了。
比如,一个很切实的应用,我们每当发表了一篇新日志后需要给所有该日志的订阅者发个邮件通知, 如果按照通常的方式就是:
日志写完 -> 点提交按钮 -> 日志插入到数据库 -> 发送邮件通知 -> 告知撰写者发布成功
那么作者在点提交按钮到看到成功提示之间可能会等待很常时间,基本是在等邮件发送的过程,比如连接邮件服务异常、或器缓慢或是订阅者太多。而实际上是不管邮件发送成功与否,保证日志保存成功基本可接受的,所以等待邮件发送的过程是很不经济的,这个过程可异步来执行,并且邮件发送的结果不太关心或以日志形式记录备查。
改进后的流程就是:
日志写完 -> 点提交按钮 -> 日志插入到数据库 ---> 告知撰写者发布成功
                                                           └ 发送邮件通知 -> [记下日志]
写个实际的程序来测试一下,有两个文件,分别是 write.php 和 sendmail.php,在 sendmail.php 用 sleep(seconds) 来模拟程序执行所使用时间。
write.php,执行耗时 1 秒:
 <?php  
  function asyn_sendmail() 
     { 
         $fp = fsockopen('localhost',80,&$errno,&$errstr,5);  
      if(!$fp)
         {
            echo "$errstr ($errno)<br />/n";
         } 
     sleep(1); 
     fputs($fp,"GET /sendmail.php?param=1/r/n"); #请求的资源 URL 一定要写对 
     fclose($fp); 
    }  
 echo time().'<br>'; 
 echo 'call asyn_sendmail<br>'; 
 asyn_sendmail(); 
 echo time().'<br>';

sendmail.php,执行耗时 10 秒:
<?php 
sleep(10); 
fopen("C:/" . time(),  "w"); 

通过页面访问 write.php,页面输出:
1272472697
call asyn_sendmail
1272472698
并且在 C:/ 生成文件:
1272472708
从上面的结果可以看出 sendmail.php 至少花费 10 秒,但不会阻塞 write.php 继续往下执行,表明这一过程是异步的。
PHP 相关文章推荐
虚拟主机中对PHP的特殊设置
Oct 09 PHP
php 计算两个时间戳相隔的时间的函数(小时)
Dec 18 PHP
一个显示某段时间内每个月的方法 返回由这些月份组成的数组
May 16 PHP
ThinkPHP中URL路径访问与模块控制器之间的关系
Aug 23 PHP
thinkphp模板输出技巧汇总
Nov 24 PHP
php获取CSS文件中图片地址并下载到本地的方法
Dec 02 PHP
PHP判断浏览器、判断语言代码分享
Mar 05 PHP
Centos PHP 扩展Xchche的安装教程
Jul 09 PHP
php实现异步将远程链接上内容(图片或内容)写到本地的方法
Nov 30 PHP
PHP实现断点续传乱序合并文件的方法
Sep 06 PHP
php菜单/评论数据递归分级算法的实现方法
Aug 01 PHP
Yii框架操作cookie与session的方法实例详解
Sep 04 PHP
基于PHP异步执行的常用方式详解
Jun 03 #PHP
php生成二维码的几种方式整理及使用实例
Jun 03 #PHP
深入PHP异步执行的详解
Jun 03 #PHP
php实现自动获取生成文章主题关键词功能的深入分析
Jun 03 #PHP
基于MySQL到MongoDB简易对照表的详解
Jun 03 #PHP
PHP Error与Logging函数的深入理解
Jun 03 #PHP
作为PHP程序员应该了解MongoDB的五件事
Jun 03 #PHP
You might like
PHP读写文件的方法(生成HTML)
2006/11/27 PHP
PHP函数常用用法小结
2010/02/08 PHP
四种php中webservice实现的简单架构方法及实例
2015/02/03 PHP
Zend Framework入门教程之Zend_Registry组件用法详解
2016/12/09 PHP
niceTitle 基于jquery的超链接提示插件
2010/05/31 Javascript
jQueryUI的Dialog的简单封装
2010/06/07 Javascript
js面向对象设计用{}好还是function(){}好(构造函数)
2011/10/23 Javascript
jQuery ajax(复习)—Baidu ajax request分离版
2013/01/24 Javascript
Function.prototype.call.apply结合用法分析示例
2013/07/03 Javascript
在父页面调用子页面的JS方法
2013/09/29 Javascript
jquery实现实时改变网页字体大小、字体背景色和颜色的方法
2015/08/05 Javascript
JS动态给对象添加事件的简单方法
2016/07/19 Javascript
JS实现表单多文件上传样式美化支持选中文件后删除相关项
2016/09/30 Javascript
react native带索引的城市列表组件的实例代码
2017/08/08 Javascript
详解vue-cli与webpack结合如何处理静态资源
2017/09/19 Javascript
jQuery实现所有验证通过方可提交的表单验证
2017/11/21 jQuery
JS同步、异步、延迟加载的方法
2018/05/05 Javascript
解决vue-cli3 使用子目录部署问题
2018/07/19 Javascript
基于JavaScript实现每日签到打卡轨迹功能
2018/11/29 Javascript
JavaScript实现移动小精灵的案例代码
2020/12/12 Javascript
[35:29]Secret vs VG 2018国际邀请赛淘汰赛BO3 第三场 8.23
2018/08/24 DOTA
Python爬虫工程师面试问题总结
2018/03/22 Python
Python文本统计功能之西游记用字统计操作示例
2018/05/07 Python
mac下给python3安装requests库和scrapy库的实例
2018/06/13 Python
用pandas中的DataFrame时选取行或列的方法
2018/07/11 Python
Python wxPython库Core组件BoxSizer用法示例
2018/09/03 Python
解决python中画图时x,y轴名称出现中文乱码的问题
2019/01/29 Python
python-docx文件定位读取过程(尝试替换)
2020/02/13 Python
Python环境搭建过程从安装到Hello World
2021/02/05 Python
解决Python import .pyd 可能遇到路径的问题
2021/03/04 Python
HTML5拖拽功能实现的拼图游戏
2018/07/31 HTML / CSS
SHEIN台湾:购买最新流行女装服饰
2019/05/18 全球购物
4s店总经理岗位职责
2013/12/31 职场文书
2014年向国旗敬礼活动总结
2014/09/27 职场文书
2014年乡镇党建工作总结
2014/11/11 职场文书
2016年社区服务活动总结
2016/04/06 职场文书