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 相关文章推荐
ZF等常用php框架中存在的问题
Jan 10 PHP
php 信息采集程序代码
Mar 17 PHP
php中判断字符串是否全是中文或含有中文的实现代码
Sep 16 PHP
探讨php define()函数及defined()函数使用详解
Jun 09 PHP
使用swoole扩展php websocket示例
Feb 13 PHP
destoon整合UCenter图文教程
Jun 21 PHP
php 判断字符串编码是utf-8 或gb2312实例
Nov 01 PHP
php+mysql+jquery实现日历签到功能
Feb 27 PHP
php cli模式下获取参数的方法
May 05 PHP
Laravle eloquent 多对多模型关联实例详解
Nov 22 PHP
PHP实现普通hash分布式算法简单示例
Aug 06 PHP
php生成随机数/生成随机字符串的方法小结【5种方法】
May 27 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加入ftp扩展的解决方法
2013/02/07 PHP
php中生成随机密码的自定义函数代码
2013/10/21 PHP
百度ping方法使用示例 自动ping百度
2014/01/26 PHP
php解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题
2014/06/19 PHP
php生成rss类用法实例
2015/04/14 PHP
PHP编程计算两个时间段是否有交集的实现方法(不算边界重叠)
2017/05/30 PHP
PHP如何根据文件头检测文件类型实例代码
2018/10/14 PHP
laravel中数据显示方法(默认值和下拉option默认选中)
2019/10/11 PHP
Javascript的并行运算实现代码
2010/11/19 Javascript
JavaScript原生对象之Number对象的属性和方法详解
2015/03/13 Javascript
用svg制作富有动态的tooltip
2015/07/17 Javascript
javascript实现二级级联菜单的简单制作
2015/11/19 Javascript
Jquery实现纵向横向菜单
2016/01/24 Javascript
AJAX实现瀑布流触发分页与分页触发瀑布流的方法
2016/05/23 Javascript
nodejs加密Crypto的实例代码
2016/07/07 NodeJs
JS实现本地存储信息的方法(基于localStorage与userData)
2017/02/18 Javascript
Node.js中Bootstrap-table的两种分页的实现方法
2017/09/18 Javascript
浅谈Vue组件及组件的注册方法
2018/08/24 Javascript
12个提高JavaScript技能的概念(小结)
2019/05/09 Javascript
在layui.use 中自定义 function 的正确方法
2019/09/16 Javascript
[01:18:21]EG vs TNC Supermajor小组赛B组败者组第一轮 BO3 第一场 6.2
2018/06/03 DOTA
[01:01:52]DOTA2-DPC中国联赛正赛 iG vs LBZS BO3 第一场 3月4日
2021/03/11 DOTA
python实现连续图文识别
2018/12/18 Python
Pycharm新手教程(只需要看这篇就够了)
2019/06/18 Python
Python Websocket服务端通信的使用示例
2020/02/25 Python
将 Ubuntu 16 和 18 上的 python 升级到最新 python3.8 的方法教程
2020/03/11 Python
Python几种常见算法汇总
2020/06/02 Python
Django中ORM的基本使用教程
2020/12/22 Python
印度最好的在线药品订购网站:PharmEasy
2018/11/30 全球购物
公司JAVA开发面试题
2015/04/02 面试题
解释下列WebService名词:WSDL、SOAP、UDDI
2012/06/22 面试题
开会迟到检讨书
2014/01/08 职场文书
举起手来观后感
2015/06/09 职场文书
python通过函数名调用函数的几种方法总结
2021/06/07 Python
mysql的单列多值存储实例详解
2022/04/05 MySQL
Java后端 Dubbo retries 超时重试机制的解决方案
2022/04/14 Java/Android