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环境搭建最新方法
Sep 05 PHP
PHP中的正规表达式(二)
Oct 09 PHP
PHP面向对象分析设计的经验原则
Sep 20 PHP
php 3行代码的分页算法(求起始页和结束页)
Oct 21 PHP
PHP数据类型之布尔型的介绍
Apr 28 PHP
php获取服务器端mac和客户端mac的地址支持WIN/LINUX
May 15 PHP
ThinkPHP中公共函数路径和配置项路径的映射分析
Nov 22 PHP
php实现按指定大小等比缩放生成上传图片缩略图的方法
Dec 15 PHP
PHP安装memcache扩展的步骤讲解
Feb 14 PHP
PHP面向对象程序设计重载(overloading)操作详解
Jun 13 PHP
php设计模式之代理模式分析【星际争霸游戏案例】
Mar 23 PHP
PHP RabbitMQ消息列队
May 11 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
PHP中文URL编解码(urlencode()rawurlencode()
2010/07/03 PHP
PHP系列学习之日期函数使用介绍
2012/08/18 PHP
关于Iframe如何跨域访问Cookie和Session的解决方法
2013/04/15 PHP
php读取文件内容的几种方法详解
2013/06/26 PHP
PHP登录(ajax提交数据和后台校验)实例分享
2016/12/29 PHP
JavaScript 组件之旅(四):测试 JavaScript 组件
2009/10/28 Javascript
jQuery语法总结和注意事项小结
2012/11/11 Javascript
JavaScript中双叹号(!!)作用示例介绍
2014/04/10 Javascript
jquery选择器排除某个DOM元素的方法(实例演示)
2014/04/25 Javascript
js浏览器本地存储store.js介绍及应用
2014/05/13 Javascript
jQuery中click事件的定义和用法
2014/12/20 Javascript
jQuery实现图片向左向右切换效果的简单实例
2016/05/18 Javascript
Bootstrap编写一个在当前网页弹出可关闭的对话框 非弹窗
2016/06/30 Javascript
ES6新特征数字、数组、字符串
2016/10/01 Javascript
vue.js实现仿原生ios时间选择组件实例代码
2016/12/21 Javascript
JavaScript拖动层Div代码
2017/03/01 Javascript
JavaScript DOM元素常见操作详解【添加、删除、修改等】
2018/05/09 Javascript
vue-cli项目代理proxyTable配置exclude的方法
2018/09/20 Javascript
如何让Nodejs支持H5 History模式(connect-history-api-fallback源码分析)
2019/05/30 NodeJs
vue自定义标签和单页面多路由的实现代码
2020/05/03 Javascript
解析Mac OS下部署Pyhton的Django框架项目的过程
2016/05/03 Python
Flask框架Flask-Principal基本用法实例分析
2018/07/23 Python
Python Pexpect库的简单使用方法
2019/01/29 Python
python实现给微信指定好友定时发送消息
2019/04/29 Python
python3 selenium自动化 frame表单嵌套的切换方法
2019/08/23 Python
Tensorflow轻松实现XOR运算的方式
2020/02/03 Python
美国巧克力喷泉品牌:Sephra
2019/05/05 全球购物
StubHub美国:购买或出售您的门票
2019/07/09 全球购物
网络教育毕业生自我鉴定
2013/10/10 职场文书
研发工程师的岗位职责
2013/11/18 职场文书
军训鉴定表自我鉴定
2014/02/13 职场文书
村党支部书记承诺书
2014/05/29 职场文书
2014年党员自我评议对照检查材料
2014/09/20 职场文书
2016师德师风学习心得体会
2016/01/12 职场文书
Python3 如何开启自带http服务
2021/05/18 Python
python实现双链表
2022/05/25 Python