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 相关文章推荐
如何将数据从文本导入到mysql
Oct 09 PHP
PHP 页面跳转到另一个页面的多种方法方法总结
Jul 07 PHP
PHP查询数据库中满足条件的记录条数(两种实现方法)
Jan 29 PHP
PHP实现返回JSON和XML的类分享
Jan 28 PHP
Yii实现简单分页的方法
Apr 29 PHP
php封装的表单验证类完整实例
Oct 19 PHP
PHP中的多种加密技术及代码示例解析
Oct 20 PHP
php常用经典函数集锦【数组、字符串、栈、队列、排序等】
Aug 23 PHP
浅谈PHP array_search 和 in_array 函数效率问题
Oct 15 PHP
Laravel框架基础语法与知识点整理【模板变量、输出、include引入子视图等】
Dec 03 PHP
用php实现分页效果的示例代码
Dec 10 PHP
PHP面试题 wakeup魔法 Ezpop pop序列化与反序列化
Apr 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编写的简单页面跳转功能实现代码
2013/11/27 PHP
PHP中如何防止外部恶意提交调用ajax接口
2016/04/11 PHP
PHP创建多级目录的两种方法
2016/10/28 PHP
PHP unset函数原理及使用方法解析
2020/08/14 PHP
jQuery 页面 Mask实现代码
2010/01/09 Javascript
jquery1.4 教程二 ajax方法的改进
2010/02/25 Javascript
JS中自定义定时器让它在某一时刻执行
2014/09/02 Javascript
JSON取值前判断
2014/12/23 Javascript
jQuery代码实现发展历程时间轴特效
2015/07/30 Javascript
jQuery中的ajax async同步和异步详解
2015/09/29 Javascript
JavaScript的代码编写格式规范指南
2015/12/07 Javascript
Angular2 多级注入器详解及实例
2016/10/30 Javascript
深究AngularJS之ui-router详解
2017/06/13 Javascript
Require.js的基本用法详解
2017/07/03 Javascript
js插件实现图片滑动验证码
2020/09/29 Javascript
VueJs 搭建Axios接口请求工具
2017/11/20 Javascript
vue-cli项目优化方法- 缩短首屏加载时间
2018/04/01 Javascript
Element Input组件分析小结
2018/10/11 Javascript
微信小程序遍历Echarts图表实现多个饼图
2019/04/25 Javascript
vue v-for直接循环数字实例
2019/11/07 Javascript
element跨分页操作选择详解
2020/06/29 Javascript
JavaScript实现矩形块大小任意缩放
2020/08/25 Javascript
使用python BeautifulSoup库抓取58手机维修信息
2013/11/21 Python
python快速查找算法应用实例
2014/09/26 Python
Python语法快速入门指南
2015/10/12 Python
python开头的coding设置方法
2019/08/08 Python
pytorch绘制并显示loss曲线和acc曲线,LeNet5识别图像准确率
2020/01/02 Python
python 实现图片批量压缩的示例
2020/12/18 Python
什么是.net的Remoting技术
2016/07/08 面试题
同学聚会欢迎辞
2014/01/14 职场文书
学生会主席就职演讲稿
2014/01/14 职场文书
新闻专业学生的自我评价
2014/02/13 职场文书
保密承诺书范文
2014/03/27 职场文书
机械专业技术员求职信
2014/06/14 职场文书
食品安全汇报材料
2014/08/18 职场文书
Pandas||过滤缺失数据||pd.dropna()函数的用法说明
2021/05/14 Python