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生成的html meta和link标记在body标签里 顶部有个空行
May 18 PHP
PHP中删除变量时unset()和null的区别分析
Jan 27 PHP
把1316这个数表示成两个数的和,其中一个为13的倍数,另一个是11的倍数,求这两个数。
Jun 24 PHP
php实现用于计算执行时间的类实例
Apr 18 PHP
php resizeimage 部分jpg文件 生成缩略图失败的原因分析及解决办法
Mar 23 PHP
PHP实现可自定义样式的分页类
Mar 29 PHP
php微信开发之音乐回复功能
Jun 14 PHP
Laravel框架运行出错提示RuntimeException No application encryption key has been specified.解决方法
Apr 02 PHP
PHP-FPM 设置多pool及配置文件重写操作示例
Oct 02 PHP
PHP设计模式(四)原型模式Prototype实例详解【创建型】
May 02 PHP
PHP7 list() 函数修改
Mar 09 PHP
一文搞懂php的垃圾回收机制
Jun 18 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的面试题集,附我的答案和分析(一)
2006/11/19 PHP
PHP MemCached 高级缓存应用代码
2010/08/05 PHP
PHP flock 文件锁详细介绍
2012/12/29 PHP
js表格分页实现代码
2009/09/18 Javascript
javascript操作css属性
2013/12/30 Javascript
Node.js中的缓冲与流模块详细介绍
2015/02/11 Javascript
javascript跨域的方法汇总
2015/10/23 Javascript
JavaScript File API文件上传预览
2016/02/02 Javascript
scroll事件实现监控滚动条并分页显示(zepto.js)
2016/12/18 Javascript
利用transition实现文字上下抖动的效果
2017/01/21 Javascript
jquery uploadify如何取消已上传成功文件
2017/02/08 Javascript
nodejs连接mysql数据库简单封装示例-mysql模块
2017/04/10 NodeJs
30分钟快速入门掌握ES6/ES2015的核心内容(上)
2018/04/18 Javascript
JavaScript隐式类型转换代码实例
2020/05/29 Javascript
使用JavaScript实现网页秒表功能(含开始、暂停、继续、重置功能)
2020/06/05 Javascript
Vue实现摇一摇功能(兼容ios13.3以上)
2021/01/26 Vue.js
Python内置函数dir详解
2015/04/14 Python
使用Python中的greenlet包实现并发编程的入门教程
2015/04/16 Python
python简单判断序列是否为空的方法
2015/06/30 Python
Python使用gensim计算文档相似性
2016/04/10 Python
Django的分页器实例(paginator)
2017/12/01 Python
对python条件表达式的四种实现方法小结
2019/01/30 Python
python3 json数据格式的转换(dumps/loads的使用、dict to str/str to dict、json字符串/字典的相互转换)
2019/04/01 Python
Python学习笔记之Django创建第一个数据库模型的方法
2019/08/07 Python
Python序列对象与String类型内置方法详解
2019/10/22 Python
使用OpenCV circle函数图像上画圆的示例代码
2019/12/27 Python
浅谈Python访问MySQL的正确姿势
2020/01/07 Python
Python绘制K线图之可视化神器pyecharts的使用
2021/03/02 Python
html5基础教程常用技巧整理
2013/08/20 HTML / CSS
一道写SQL的面试题和答案
2013/11/19 面试题
信息总监管理职责范本
2014/03/08 职场文书
《生命的药方》教学反思
2014/04/08 职场文书
知识改变命运演讲稿
2014/05/21 职场文书
自我管理的活动方案
2014/08/25 职场文书
JavaScript分页组件使用方法详解
2021/07/26 Javascript
python中tkinter复选框使用操作
2021/11/11 Python