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 相关文章推荐
开源SNS系统-ThinkSNS
May 18 PHP
php checkdate、getdate等日期时间函数操作详解
Mar 11 PHP
PHP开发需要注意的安全问题
Sep 01 PHP
《PHP编程最快明白》第七讲:php图片验证码与缩略图
Nov 01 PHP
PHP中将字符串转化为整数(int) intval() printf() 性能测试
Mar 20 PHP
浅析PHP页面局部刷新功能的实现小结
Jun 21 PHP
PHP的password_hash()使用实例
Mar 17 PHP
Windows下的PHP安装文件线程安全和非线程安全的区别
Apr 23 PHP
Thinkphp中volist标签mod控制一定记录的换行BUG解决方法
Nov 04 PHP
PHP简单判断字符串是否包含另一个字符串的方法
Mar 25 PHP
php制作基于xml的RSS订阅源功能示例
Feb 08 PHP
PHP新手指南
Apr 01 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中常用编辑器推荐
2007/01/02 PHP
精通php的十大要点(上)
2009/02/04 PHP
PHP输出XML到页面的3种方法详解
2013/06/06 PHP
PHP5多态性与动态绑定介绍
2015/04/03 PHP
php微信公众平台开发之微信群发信息
2016/09/13 PHP
php array_walk 对数组中的每个元素应用用户自定义函数详解
2016/11/18 PHP
thinkPHP实现的省市区三级联动功能示例
2017/05/05 PHP
PHP框架Laravel中实现supervisor执行异步进程的方法
2017/06/07 PHP
java script编程起步(第三课)
2007/01/10 Javascript
JavaScript 封装Ajax传递的数据代码
2009/06/05 Javascript
编写Js代码要注意的几条规则
2010/09/10 Javascript
关于jquery性能最佳实践的讨论,与求教
2012/03/30 Javascript
JS函数实现动态添加CSS样式表文件
2012/12/15 Javascript
js解析与序列化json数据(二)序列化探讨
2013/02/01 Javascript
css样式标签和js语法属性区别
2013/11/06 Javascript
js控制容器隐藏出现防止样式变化的两种方法
2014/04/25 Javascript
node.js中的fs.lchmodSync方法使用说明
2014/12/16 Javascript
javascript实现捕捉键盘上按下的键
2015/05/05 Javascript
JS基于Mootools实现的个性菜单效果代码
2015/10/21 Javascript
详解vue express启动数据服务
2017/07/05 Javascript
webpack自动打包和热更新的实现方法
2019/06/24 Javascript
小程序实现投票进度条
2019/11/20 Javascript
用JavaScript实现贪吃蛇游戏
2020/10/23 Javascript
解决Vue keep-alive 调用 $destory() 页面不再被缓存的情况
2020/10/30 Javascript
[17:13]DOTA2 HEROS教学视频教你分分钟做大人-斯拉克
2014/06/13 DOTA
Python 过滤字符串的技巧,map与itertools.imap
2008/09/06 Python
浅析Python中的多重继承
2015/04/28 Python
python进程管理工具supervisor的安装与使用教程
2017/09/05 Python
市场总经理岗位职责
2014/04/11 职场文书
激励员工的口号
2014/06/16 职场文书
运动会广播稿200字(10篇)
2014/10/12 职场文书
校车司机安全责任书
2015/05/11 职场文书
2016年教师节贺卡寄语
2015/12/04 职场文书
小程序实现筛子抽奖
2021/05/26 Javascript
总结Python使用过程中的bug
2021/06/18 Python
Python编写nmap扫描工具
2021/07/21 Python