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 相关文章推荐
一个ORACLE分页程序,挺实用的.
Oct 09 PHP
PHP学习之正则表达式
Apr 17 PHP
php中获取指定IP的物理地址的代码(正则表达式)
Jun 23 PHP
destoon实现VIP排名一直在前面排序的方法
Aug 21 PHP
PHP异常处理浅析
May 12 PHP
PHP框架Laravel学习心得体会
Oct 28 PHP
PHP 5.6.11中CURL模块问题的解决方法
Aug 08 PHP
php加密解密字符串示例
Oct 13 PHP
php通过会话控制实现身份验证实例
Oct 18 PHP
PHP magento后台无法登录问题解决方法
Nov 24 PHP
thinkphp5.0整合phpsocketio完整攻略(绕坑)
Oct 12 PHP
php 防护xss,PHP的防御XSS注入的终极解决方案
Apr 01 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
支持oicq头像的留言簿(一)
2006/10/09 PHP
php中使用接口实现工厂设计模式的代码
2012/06/17 PHP
PHP实现返回JSON和XML的类分享
2015/01/28 PHP
php curl模拟post请求和提交多维数组的示例代码
2015/11/19 PHP
Zend Framework教程之Zend_Controller_Plugin插件用法详解
2016/03/07 PHP
关于ThinkPhp 框架表单验证及ajax验证问题
2017/07/19 PHP
Laravel Validator 实现两个或多个字段联合索引唯一
2019/05/08 PHP
JavaScript 拾碎[三] 使用className属性
2010/10/16 Javascript
2则自己编写的jQuery特效分享
2015/02/26 Javascript
JS判断页面是否出现滚动条的方法
2015/07/17 Javascript
JS中改变this指向的方法(call和apply、bind)
2016/03/26 Javascript
jQuery.ajax 跨域请求webapi设置headers的解决方案
2016/08/08 Javascript
js省市区级联查询(插件版&amp;无插件版)
2017/03/21 Javascript
JavaScript正则表达式的贪婪匹配和非贪婪匹配
2017/09/05 Javascript
深入理解Vue官方文档梳理之全局API
2017/11/22 Javascript
vue利用axios来完成数据的交互
2018/03/23 Javascript
vue中的计算属性实例详解
2018/09/19 Javascript
JS中验证整数和小数的正则表达式
2018/10/08 Javascript
vue-week-picker实现支持按周切换的日历
2019/06/26 Javascript
基于JavaScript判断两个对象内容是否相等
2020/01/10 Javascript
如何在vue中使用kindeditor富文本编辑器
2020/12/19 Vue.js
vue element el-transfer增加拖拽功能
2021/01/15 Vue.js
[55:35]DOTA2-DPC中国联赛 正赛 CDEC vs Dragon BO3 第二场 1月22日
2021/03/11 DOTA
记录Django开发心得
2014/07/16 Python
python 读写中文json的实例详解
2017/10/29 Python
Python使用reportlab模块生成PDF格式的文档
2019/03/11 Python
tensorflow使用range_input_producer多线程读取数据实例
2020/01/20 Python
Python restful框架接口开发实现
2020/04/13 Python
python 读取.nii格式图像实例
2020/07/01 Python
绝对经典成功的大学生推荐信
2013/11/08 职场文书
教师的实习自我鉴定
2013/12/17 职场文书
公司年会晚宴演讲稿
2014/01/06 职场文书
员工安全生产责任书
2014/07/22 职场文书
于丹讲座视频观后感
2015/06/15 职场文书
八年级历史教学反思
2016/02/19 职场文书
Pygame Time时间控制的具体使用详解
2021/11/17 Python