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 相关文章推荐
ip签名探针
Oct 09 PHP
在php中取得image按钮传递的name值
Oct 09 PHP
利用phpExcel实现Excel数据的导入导出(全步骤详细解析)
Nov 26 PHP
php实现删除指定目录下相关文件的方法
Oct 20 PHP
PHP积分兑换接口实例
Feb 09 PHP
php中smarty区域循环的方法
Jun 11 PHP
PHP爬虫之百万级别知乎用户数据爬取与分析
Jan 22 PHP
微信支付扫码支付php版
Jul 22 PHP
php基于单例模式封装mysql类完整实例
Oct 18 PHP
PHP call_user_func和call_user_func_array函数的简单理解与应用分析
Nov 25 PHP
PHP设计模式(八)装饰器模式Decorator实例详解【结构型】
May 02 PHP
PHP中SESSION过期设置
Mar 09 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
html中select语句读取mysql表中内容
2006/10/09 PHP
PHP 5.5 创建和验证哈希最简单的方法详解
2013/11/07 PHP
体育彩票排列三组选三算法分享
2014/03/07 PHP
PHP实现的贪婪算法实例
2017/10/17 PHP
PHP对称加密算法(DES/AES)类的实现代码
2017/11/14 PHP
PHP7 字符串处理机制修改
2021/03/09 PHP
jQuery)扩展jQuery系列之一 模拟alert,confirm(一)
2010/12/04 Javascript
Json字符串转换为JS对象的高效方法实例
2013/05/01 Javascript
编写js扩展方法判断一个数组中是否包含某个元素
2013/11/08 Javascript
理解javascript回调函数
2014/12/28 Javascript
javascript实现表格排序 编辑 拖拽 缩放
2015/01/02 Javascript
解析JavaScript面向对象概念中的Object类型与作用域
2016/05/10 Javascript
微信小程序 数据访问实例详解
2016/10/08 Javascript
AngularJS使用ng-Cloak阻止初始化闪烁问题的方法
2016/11/03 Javascript
通过js示例讲解时间复杂度与空间复杂度
2019/08/06 Javascript
Python模块包中__init__.py文件功能分析
2016/06/14 Python
用python与文件进行交互的方法
2018/03/01 Python
Python中py文件引用另一个py文件变量的方法
2018/04/29 Python
Python生成MD5值的两种方法实例分析
2019/04/26 Python
python3.7环境下安装Anaconda的教程图解
2019/09/10 Python
如何使用python实现模拟鼠标点击
2020/01/06 Python
python读取mysql数据绘制条形图
2020/03/25 Python
使用python批量转换文件编码为UTF-8的实现
2020/04/03 Python
Pyqt助手安装PyQt5帮助文档过程图解
2020/11/20 Python
css3实现的下拉菜单效果示例
2014/01/22 HTML / CSS
HTML5本地存储之Database Storage应用介绍
2013/01/06 HTML / CSS
家居饰品店创业计划书
2014/01/31 职场文书
青春奉献演讲稿
2014/05/08 职场文书
酒店开业策划方案
2014/06/02 职场文书
关于感恩的演讲稿800字
2014/08/26 职场文书
上班时间打瞌睡检讨书
2014/09/26 职场文书
课外活动总结
2015/02/04 职场文书
集结号观后感
2015/06/08 职场文书
军训心得体会范文(2016最新篇)
2016/01/11 职场文书
2016道德模范先进事迹材料
2016/02/26 职场文书
Matplotlib绘制混淆矩阵的实现
2021/05/27 Python