php事件驱动化设计详解


Posted in PHP onNovember 10, 2016

本文实例讲述了php事件驱动化设计。分享给大家供大家参考,具体如下:

最近在做一个需要用到异步php的项目, 翻阅php源码的时候,发现了三个没有用过的模块,sysvsem,sysvshm,sysvmsg,一番研究以后,受益非浅。

在php中有这么一族函数,他们是对unix的v ipc函数族的包装。
它们很少被人们用到,但是它们却很强大。巧妙的运用它们,可以让你事倍功半。

它们包括:

信号量(semaphores)
共享内存(shared memory)
进程间通信(inter-process messaging, ipc)

基于这些,我们完全有可能将php包装成一基于消息驱动的系统。

但是,首先,我们需要介绍几个重要的基础:

1. ftok

int ftok ( string pathname, string proj )

ftok将一个路径名pathname和一个项目名(必须为一个字符), 转化成一个整形的用来使用系统v ipc的key

2. ticks

ticks是从php 4.0.3开始才加入到php中的,它是一个在 declare 代码段中解释器每执行 n 条低级语句就会发生的事件。n 的值是在 declare 中的 directive 部分用 ticks=n 来指定的。

function getstatus($arg){
  print_r(connection_status());
  debug_print_backtrace();
}
reigster_tick_function("getstatus", true);
declare(ticks=1){
  for($i =1; $i<999; $i++){
 echo "hello";
 }
}
unregister_tick_function("getstatus");

这个就基本相当于:

function getstatus($arg){
  print_r(connection_status());
  debug_print_backtrace();
}
reigster_tick_function("getstatus", true);
declare(ticks=1){
  for($i =1; $i<999; $i++){
 echo "hello"; getstatus(true);
 }
}
unregister_tick_function("getstatus");

消息,我现在用一个例子来说明,如何结合ticks来实现php的消息通信。

$mesg_key = ftok(__file__, 'm');
$mesg_id = msg_get_queue($mesg_key, 0666);
function fetchmessage($mesg_id){
 if(!is_resource($mesg_id)){
  print_r("mesg queue is not ready");
 }
 if(msg_receive($mesg_id, 0, $mesg_type, 1024, $mesg, false, msg_ipc_nowait)){
  print_r("process got a new incoming msg: $mesg ");
 }
}
register_tick_function("fetchmessage", $mesg_id);
declare(ticks=2){
 $i = 0;
 while(++$i < 100){
  if($i%5 == 0){
msg_send($mesg_id, 1, "hi: now index is :". $i);
  }
 }
}
//msg_remove_queue($mesg_id);

在这个例子中,首先将我们的php执行process加入到一个由ftok生成的key所获得的消息队列中。

然后,通过ticks,没隔俩个语句,就去查询一次消息队列。

然后模拟了消息发送。

在浏览器访问这个脚本,结果如下:

process got a new incoming msg: s:19:"hi: now index is :5";
process got a new incoming msg: s:20:"hi: now index is :10";
process got a new incoming msg: s:20:"hi: now index is :15";
process got a new incoming msg: s:20:"hi: now index is :20";
process got a new incoming msg: s:20:"hi: now index is :25";
process got a new incoming msg: s:20:"hi: now index is :30";
process got a new incoming msg: s:20:"hi: now index is :35";
process got a new incoming msg: s:20:"hi: now index is :40";
process got a new incoming msg: s:20:"hi: now index is :45";
process got a new incoming msg: s:20:"hi: now index is :50";
process got a new incoming msg: s:20:"hi: now index is :55";
process got a new incoming msg: s:20:"hi: now index is :60";
process got a new incoming msg: s:20:"hi: now index is :65";
process got a new incoming msg: s:20:"hi: now index is :70";
process got a new incoming msg: s:20:"hi: now index is :75";
process got a new incoming msg: s:20:"hi: now index is :80";
process got a new incoming msg: s:20:"hi: now index is :85";
process got a new incoming msg: s:20:"hi: now index is :90";
process got a new incoming msg: s:20:"hi: now index is :95";

看到这里是不是,大家已经对怎么模拟php为事件驱动已经有了一个概念了? 别急,我们继续完善。

2. 信号量

信号量的概念,大家应该都很熟悉。通过信号量,可以实现进程通信,竞争等。 再次就不赘述了,只是简单的列出php中提供的信号量函数集

sem_acquire -- acquire a semaphore
sem_get -- get a semaphore id
sem_release -- release a semaphore
sem_remove -- remove a semaphore

具体信息,可以翻阅php手册。

3. 内存共享

php sysvshm提供了一个内存共享方案:sysvshm,它是和sysvsem,sysvmsg一个系列的,但在此处,我并没有使用它,我使用的shmop系列函数,结合ticks

function memoryusage(){
 printf("%s: %s<br/>", date("h:i:s",time()), memory_get_usage());
 //var_dump(debug_backtrace());
 //var_dump(__function__);
 //debug_print_backtrace();
}
register_tick_function("memoryusage");
declare(ticks=1){
$shm_key = ftok(__file__, 's');
$shm_id = shmop_open($shm_key, 'c', 0644, 100);
}
printf("size of shared memory is: %s<br/>", shmop_size($shm_id));
$shm_text = shmop_read($shm_id, 0, 100);
eval($shm_text);
if(!empty($share_array)){
 var_dump($share_array);
 $share_array['id'] += 1;
}else{
 $share_array = array('id' => 1);
}
$out_put_str = "$share_array = " . var_export($share_array, true) .";";
$out_put_str = str_pad($out_put_str, 100, " ", str_pad_right);
shmop_write($shm_id, $out_put_str, 0);
?>

运行这个例子,不断刷新,我们可以看到index在递增。

单单使用这个shmop就能完成一下,php脚本之间共享数据的功能:以及,比如缓存,计数等等。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP性能优化准备篇图解PEAR安装
Dec 05 PHP
phpMyAdmin出现无法载入 mcrypt 扩展,请检查PHP配置的解决方法
Mar 26 PHP
php插入中文到sqlserver 2008里出现乱码的解决办法分享
Jul 19 PHP
PHP 验证码不显示只有一个小红叉的解决方法
Sep 30 PHP
浅析ThinkPHP的模板输出功能
Jul 01 PHP
php获取json数据所有的节点路径
May 17 PHP
PHP 中提示undefined index如何解决(多种方法)
Mar 16 PHP
PHP怎样用正则抓取页面中的网址
Aug 09 PHP
php批量转换文件夹下所有文件编码的函数类
Aug 06 PHP
thinkphp5.1 文件引入路径问题及注意事项
Jun 13 PHP
ThinkPHP3.2框架自定义配置和加载用法示例
Jun 14 PHP
PHP使用Http Post请求发送Json对象数据代码解析
Jul 16 PHP
PHP的消息通信机制测试实例
Nov 10 #PHP
PHP使用GD库输出汉字的方法【测试可用】
Nov 10 #PHP
Yii2框架RESTful API 格式化响应,授权认证和速率限制三部分详解
Nov 10 #PHP
PHP基于反射机制实现插件的可插拔设计详解
Nov 10 #PHP
PHP yii实现model添加默认值的方法(两种方法)
Nov 10 #PHP
PHP实现的曲线统计图表示例
Nov 10 #PHP
PHP  Yii清理缓存的实现方法
Nov 10 #PHP
You might like
第五节--克隆
2006/11/16 PHP
用PHP读取RSS feed的代码
2008/08/01 PHP
PHP解决URL中文GBK乱码问题的两种方法
2014/06/03 PHP
PHP实现通过中文字符比率来判断垃圾评论的方法
2014/10/20 PHP
jquery+thinkphp实现跨域抓取数据的方法
2016/10/15 PHP
实例讲解YII2中多表关联的使用方法
2017/07/21 PHP
初试jQuery EasyUI 使用介绍
2010/04/01 Javascript
DIV菜单层实现代码
2010/11/19 Javascript
jQuery为iframe的body添加click事件的实现代码
2011/04/07 Javascript
js前端实现多图图片上传预览的两个方法(推荐)
2016/11/18 Javascript
JavaScript 自定义事件之我见
2017/09/25 Javascript
JS实现带动画的回到顶部效果
2017/12/28 Javascript
基于vue-resource jsonp跨域问题的解决方法
2018/02/03 Javascript
小程序测试后台服务的方法(ngrok)
2019/03/08 Javascript
Vue图片浏览组件v-viewer用法分析【支持旋转、缩放、翻转等操作】
2019/11/04 Javascript
js实现轮播图效果 z-index实现轮播图
2020/01/17 Javascript
浅析TypeScript 命名空间
2020/03/19 Javascript
webpack 如何同时输出压缩和未压缩的文件的实现步骤
2020/06/05 Javascript
[02:11]2016国际邀请赛中国区预选赛最美TA采访现场玩家
2016/06/28 DOTA
python 图片验证码代码分享
2012/07/04 Python
python中numpy包使用教程之数组和相关操作详解
2017/07/30 Python
浅谈机器学习需要的了解的十大算法
2017/12/15 Python
Python实现抓取HTML网页并以PDF文件形式保存的方法
2018/05/08 Python
python保存网页图片到本地的方法
2018/07/24 Python
python中如何使用分步式进程计算详解
2019/03/22 Python
python中tkinter的应用:修改字体的实例讲解
2019/07/17 Python
解决Python计算矩阵乘向量,矩阵乘实数的一些小错误
2019/08/26 Python
使用python制作游戏下载进度条的代码(程序说明见注释)
2019/10/24 Python
在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern "C"
2014/08/09 面试题
Why we need EJB
2016/10/20 面试题
装潢设计实习自我鉴定
2013/09/19 职场文书
新入职员工的自我介绍演讲稿
2014/01/02 职场文书
给朋友的道歉信
2014/01/09 职场文书
医务人员医德医风心得体会
2016/01/25 职场文书
自考生自我评价
2019/06/21 职场文书
错误码NET::ERR_CERT_DATE_INVALID证书已过期解决方法?
2022/07/07 数码科技