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 09 PHP
php 服务器调试 Zend Debugger 的安装教程
Sep 25 PHP
一步一步学习PHP(4) php 函数 补充2
Feb 15 PHP
php的字符串用法小结
Jun 08 PHP
PHP面向对象的进阶学习(抽像类、接口、final、类常量)
May 07 PHP
php生成局部唯一识别码LUID的代码
Oct 06 PHP
php设置编码格式的方法
Mar 05 PHP
解析PHP中如何将数组变量写入文件
Jun 06 PHP
PHP常用的小程序代码段
Nov 14 PHP
Zend Framework教程之配置文件application.ini解析
Mar 10 PHP
PHP常用字符串函数小结(推荐)
Aug 05 PHP
laravel 验证错误信息到 blade模板的方法
Sep 29 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
Zend Guard一些常见问题解答
2008/09/11 PHP
一个PHP实现的轻量级简单爬虫
2015/07/08 PHP
laravel中命名路由的使用方法
2017/02/24 PHP
PHP实现APP微信支付的实例讲解
2018/02/10 PHP
php语法检查的方法总结
2019/01/21 PHP
JQuery 表格操作(交替显示、拖动表格行、选择行等)
2009/07/29 Javascript
javascript模拟select,jselect的方法实现
2012/11/08 Javascript
关于页面嵌入swf覆盖div层的问题的解决方法
2014/02/11 Javascript
JavaScript实现图片轮播的方法
2015/07/31 Javascript
AngularJS国际化详解及示例代码
2016/08/18 Javascript
jquery attr()设置和获取属性值实例教程
2016/09/25 Javascript
原生JS 购物车及购物页面的cookie使用方法
2017/08/21 Javascript
JavaScript使用递归和循环实现阶乘的实例代码
2018/08/28 Javascript
vue二级菜单导航点击选中事件的方法
2018/09/12 Javascript
Angular封装表单控件及思想总结
2019/12/11 Javascript
返回上一个url并刷新界面的js代码
2020/09/12 Javascript
[36:33]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第二场 11.29
2020/12/02 DOTA
使用python调用浏览器并打开一个网址的例子
2014/06/05 Python
pandas 快速处理 date_time 日期格式方法
2018/11/12 Python
Python第三方Window模块文件的几种安装方法
2018/11/22 Python
python中字符串数组逆序排列方法总结
2019/06/23 Python
python实现键盘输入的实操方法
2019/07/16 Python
django之状态保持-使用redis存储session的例子
2019/07/28 Python
Python写捕鱼达人的游戏实现
2020/03/31 Python
Python中常见的数制转换有哪些
2020/05/27 Python
Python如何定义接口和抽象类
2020/07/28 Python
加拿大鞋子连锁店:Town Shoes
2016/09/26 全球购物
澳大利亚女性快速时尚零售商:Ally Fashion
2018/04/25 全球购物
女孩每月服装订阅盒:kidpik
2019/04/17 全球购物
英语专业个人求职信范文
2014/02/01 职场文书
煤矿安全演讲稿
2014/05/09 职场文书
小学教师师德师风演讲稿
2014/08/22 职场文书
幸福中国演讲稿
2014/09/12 职场文书
python爬虫之利用selenium模块自动登录CSDN
2021/04/22 Python
python 实现体质指数BMI计算
2021/05/26 Python
Hive常用日期格式转换语法
2022/06/25 数据库