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读取30天之内的根据算法排序的代码
Apr 06 PHP
PHP extract 将数组拆分成多个变量的函数
Jun 30 PHP
基于PHP服务端图片生成缩略图的方法详解
Jun 20 PHP
解析Ubuntu下crontab命令的用法
Jun 24 PHP
shell脚本作为保证PHP脚本不挂掉的守护进程实例分享
Jul 15 PHP
不使用php api函数实现数组的交换排序示例
Apr 13 PHP
浅谈php函数serialize()与unserialize()的使用方法
Aug 19 PHP
php插入含有特殊符号数据的处理方法
Nov 24 PHP
PHP魔术方法之__call与__callStatic使用方法
Jul 23 PHP
PHP简单实现欧拉函数Euler功能示例
Nov 06 PHP
laravel框架中控制器的创建和使用方法分析
Nov 23 PHP
yii2.0框架实现上传excel文件后导入到数据库的方法示例
Apr 13 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
Discuz 6.0+ 批量注册用户名
2009/09/13 PHP
elgg 获取文件图标地址的方法
2010/03/20 PHP
spl_autoload_register与autoload的区别详解
2013/06/03 PHP
php类声明和php类使用方法示例分享
2014/03/29 PHP
分享8个Laravel模型时间戳使用技巧小结
2020/02/12 PHP
Jquery乱码的一次解决过程 图解教程
2010/02/20 Javascript
用JavaScript计算在UTF-8下存储字符串占用字节数
2013/08/08 Javascript
jQuery提示效果代码分享
2014/11/20 Javascript
JS中创建函数的三种方式及区别
2016/03/13 Javascript
Javascript实现图片懒加载插件的方法
2016/10/20 Javascript
详解利用exif.js解决ios手机上传竖拍照片旋转90度问题
2016/11/04 Javascript
Vue.js 和 MVVM 的注意事项
2016/11/07 Javascript
js实现界面向原生界面发消息并跳转功能
2016/11/22 Javascript
jQuery is not defined 错误原因与解决方法小结
2017/03/19 Javascript
Angularjs过滤器实现动态搜索与排序功能示例
2017/12/13 Javascript
Jquery和CSS实现选择框重置按钮功能
2018/11/08 jQuery
vue框架下部署上线后刷新报404问题的解决方案(推荐)
2019/04/03 Javascript
跟老齐学Python之关于循环的小伎俩
2014/10/02 Python
Python守护进程(daemon)代码实例
2015/03/06 Python
python使用xlrd实现检索excel中某列含有指定字符串记录的方法
2015/05/09 Python
python中正则的使用指南
2016/12/04 Python
python的Crypto模块实现AES加密实例代码
2018/01/22 Python
Pandas之Fillna填充缺失数据的方法
2019/06/25 Python
python 使用plt画图,去除图片四周的白边方法
2019/07/09 Python
pandas DataFrame 数据选取,修改,切片的实现
2020/04/24 Python
详解使用双缓存解决Canvas clearRect引起的闪屏问题
2019/04/29 HTML / CSS
悬挂训练绳:TRX
2017/12/14 全球购物
来自世界上最好大学的在线课程:edX
2018/10/16 全球购物
军训生自我鉴定范文
2013/12/27 职场文书
商场客服专员岗位职责
2014/06/13 职场文书
小学课外活动总结
2014/07/09 职场文书
2015年质量月活动总结报告
2015/03/27 职场文书
同意转租证明
2015/06/24 职场文书
2016年三八红旗手先进事迹材料
2016/02/26 职场文书
JavaScript继承的三种方法实例
2021/05/12 Javascript
Windows Server 2019 域控制器安装图文教程
2022/04/28 Servers