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实现文件下载断点续传详解
Oct 15 PHP
PHP实现将浏览历史页面网址保存到cookie的方法
Jan 26 PHP
php常量详细解析
Oct 27 PHP
php的闭包(Closure)匿名函数初探
Feb 14 PHP
Zend Framework教程之模型Model用法简单实例
Mar 04 PHP
orm获取关联表里的属性值
Apr 17 PHP
CI框架实现优化文件上传及多文件上传的方法
Jan 04 PHP
PHP的自定义模板引擎
Mar 24 PHP
PHP convert_cyr_string()函数讲解
Feb 13 PHP
PHP批斗大会之缺失的异常详解
Jul 09 PHP
Laravel Eloquent ORM 实现查询表中指定的字段
Oct 17 PHP
php实例化对象的实例方法
Nov 17 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
100行PHP代码实现socks5代理服务器
2016/04/28 PHP
php倒计时出现-0情况的解决方法
2016/07/28 PHP
thinkphp5引入公共部分header、footer的方法详解
2018/09/14 PHP
JQuery 学习技巧总结
2010/05/21 Javascript
从阶乘函数对比Javascript和C#的异同
2012/05/31 Javascript
jQuery的Ajax的自动完成功能控件简要说明
2013/02/22 Javascript
动态加载dtree.js树treeview(示例代码)
2013/12/17 Javascript
浅析Node在构建超媒体API中的作用
2014/07/30 Javascript
JS解析XML实例分析
2015/01/30 Javascript
详解Vue 非父子组件通信方法(非Vuex)
2017/05/24 Javascript
BootStrap 标题设置跨行无效的解决方法
2017/10/25 Javascript
在博客园博文中添加自定义右键菜单的方法详解
2020/02/05 Javascript
Node.js path模块,获取文件后缀名操作
2020/11/07 Javascript
Python3搜索及替换文件中文本的方法
2015/05/22 Python
python实现SMTP邮件发送功能
2020/06/16 Python
名片管理系统python版
2018/01/11 Python
解决python3读取Python2存储的pickle文件问题
2018/10/25 Python
Python3爬虫学习之爬虫利器Beautiful Soup用法分析
2018/12/12 Python
浅谈selenium如何应对网页内容需要鼠标滚动加载的问题
2020/03/14 Python
python右对齐的实例方法
2020/07/05 Python
Python生成器generator原理及用法解析
2020/07/20 Python
matplotlib实现数据实时刷新的示例代码
2021/01/05 Python
全球速卖通:AliExpress(国际版淘宝)
2017/09/20 全球购物
Nobody Denim官网:购买高级女士牛仔裤
2021/03/15 全球购物
应届毕业生自我评价分享
2013/12/15 职场文书
员工拓展培训方案
2014/02/15 职场文书
中等生评语大全
2014/05/04 职场文书
环保倡议书500字
2014/05/15 职场文书
党支部反对四风思想汇报
2014/10/10 职场文书
2015新年寄语大全
2014/12/08 职场文书
教师“一帮一”结对子活动总结
2015/05/07 职场文书
债务追讨律师函
2015/06/24 职场文书
财务管理制度范本
2015/08/04 职场文书
2016年母亲节广告语
2016/01/28 职场文书
JS数组方法some、every和find的使用详情
2021/10/05 Javascript
MySQL的索引你了解吗
2022/03/13 MySQL