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中集成PayPal标准支付的实现方法分享
Feb 06 PHP
基于PHP Socket配置以及实例的详细介绍
Jun 13 PHP
解析php中反射的应用
Jun 18 PHP
php session劫持和防范的方法
Nov 12 PHP
php无限遍历目录示例
Feb 21 PHP
php匹配字符中链接地址的方法
Dec 22 PHP
php微信支付之APP支付方法
Mar 04 PHP
递归实现php数组转xml的代码分享
May 14 PHP
php获取系统变量方法小结
May 29 PHP
PHP变量赋值、代入给JavaScript中的变量
Jun 29 PHP
Symfony2 session用法实例分析
Feb 04 PHP
在Laravel中使用DataTables插件的方法
May 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
提升PHP执行速度全攻略(上)
2006/10/09 PHP
解析php时间戳与日期的转换
2013/06/06 PHP
smarty模板引擎从php中获取数据的方法
2015/01/22 PHP
php中关于长度计算容易混淆的问题分析
2016/05/27 PHP
PHP简单实现上一页下一页功能示例
2016/09/14 PHP
yii2简单使用less代替css示例
2017/03/10 PHP
jQuery判断密码强度实现思路及代码
2013/04/24 Javascript
JavaScript比较两个对象是否相等的方法
2015/02/06 Javascript
JS给Array添加是否包含字符串的简单方法
2016/10/29 Javascript
vuejs响应用户事件(如点击事件)
2017/03/14 Javascript
十大 Node.js 的 Web 框架(快速提升工作效率)
2017/06/30 Javascript
vue兄弟组件传递数据的实例
2018/09/06 Javascript
vue配置文件实现代理v2版本的方法
2019/06/21 Javascript
弱类型语言javascript开发中的一些坑实例小结【变量、函数、数组、对象、作用域等】
2019/08/07 Javascript
js实现简单的秒表
2020/01/16 Javascript
Python中分数的相关使用教程
2015/03/30 Python
Python找出9个连续的空闲端口
2016/02/01 Python
Python中异常重试的解决方案详解
2017/05/05 Python
Python 多进程并发操作中进程池Pool的实例
2017/11/01 Python
人机交互程序 python实现人机对话
2017/11/14 Python
Django的分页器实例(paginator)
2017/12/01 Python
Python内置模块turtle绘图详解
2017/12/09 Python
TensorFlow卷积神经网络之使用训练好的模型识别猫狗图片
2019/03/14 Python
详解Python Opencv和PIL读取图像文件的差别
2019/12/27 Python
python分别打包出32位和64位应用程序
2020/02/18 Python
python如何将图片转换素描画
2020/09/08 Python
python利用后缀表达式实现计算器功能
2021/02/22 Python
python爬虫破解字体加密案例详解
2021/03/02 Python
eBay英国购物网站:eBay.co.uk
2019/06/19 全球购物
环境工程求职简历的自我评价范文
2013/10/24 职场文书
2014大学班主任工作总结
2014/11/08 职场文书
2015年行风建设工作总结
2015/05/15 职场文书
导游词之无锡丝业博物馆
2019/11/12 职场文书
用python修改excel表某一列内容的操作方法
2021/06/11 Python
python geopandas读取、创建shapefile文件的方法
2021/06/29 Python
JavaScript组合继承详解
2021/11/07 Javascript