PHP下操作Linux消息队列完成进程间通信的方法


Posted in PHP onJuly 24, 2010

关于Linux系统进程通信的概念及实现可查看:http://www.ibm.com/developerworks/cn/linux/l-ipc/

关于Linux系统消息队列的概念及实现可查看:http://www.ibm.com/developerworks/cn/linux/l-ipc/part4/

PHP的sysvmsg模块是对Linux系统支持的System V IPC中的System V消息队列函数族的封装。我们需要利用sysvmsg模块提供的函数来进进程间通信。先来看一段示例代码_1:

<?php 
$message_queue_key = ftok(__FILE__, 'a'); 
$message_queue = msg_get_queue($message_queue_key, 0666); 
var_dump($message_queue); 
$message_queue_status = msg_stat_queue($message_queue); 
print_r($message_queue_status); 
//向消息队列中写 
msg_send($message_queue, 1, "Hello,World!"); 
$message_queue_status = msg_stat_queue($message_queue); 
print_r($message_queue_status); 
//从消息队列中读 
msg_receive($message_queue, 0, $message_type, 1024, $message, true, MSG_IPC_NOWAIT); 
print_r($message."\r\n"); 
msg_remove_queue($message_queue); 
?>

这段代码的运行结果如下:
resource(4) of type (sysvmsg queue) 
Array 
( 
[msg_perm.uid] => 1000 
[msg_perm.gid] => 1000 
[msg_perm.mode] => 438 
[msg_stime] => 0 
[msg_rtime] => 0 
[msg_ctime] => 1279849495 
[msg_qnum] => 0 
[msg_qbytes] => 16384 
[msg_lspid] => 0 
[msg_lrpid] => 0 
) 
Array 
( 
[msg_perm.uid] => 1000 
[msg_perm.gid] => 1000 
[msg_perm.mode] => 438 
[msg_stime] => 1279849495 
[msg_rtime] => 0 
[msg_ctime] => 1279849495 
[msg_qnum] => 1 
[msg_qbytes] => 16384 
[msg_lspid] => 2184 
[msg_lrpid] => 0 
) 
Hello,World!

可以看到已成功从消息队列中读取“Hello,World!”字符串

下面列举一下示例代码中的主要函数:

ftok ( string $pathname , string $proj ) 
手册上给出的解释是:Convert a pathname and a project identifier to a System V IPC key。这个函数返回的键值唯一对应linux系统中一个消息队列。在获得消息队列的引用之前都需要调用这个函数。 
msg_get_queue ( int $key [, int $perms ] ) 
msg_get_queue()会根据传入的键值返回一个消息队列的引用。如果linux系统中没有消息队列与键值对应,msg_get_queue()将会创建一个新的消息队列。函数的第二个参数需要传入一个int值,作为新创建的消息队列的权限值,默认为0666。这个权限值与linux命令chmod中使用的数值是同一个意思,因为在linux系统中一切皆是文件。 
msg_send ( resource $queue , int $msgtype , mixed $message [, bool $serialize [, bool $blocking [, int &$errorcode ]]] ) 
顾名思义,该函数用来向消息队列中写数据。 
msg_stat_queue ( resource $queue ) 
这个函数会返回消息队列的元数据。消息队列元数据中的信息很完整,包括了消息队列中待读取的消息数、最后读写队列的进程ID等。示例代码在第8行调用该函数返回的数组中队列中待读取的消息数msg_qnum值为0。 
msg_receive ( resource $queue , int $desiredmsgtype , int &$msgtype , int $maxsize , mixed &$message [, bool $unserialize [, int $flags [, int &$errorcode ]]] ) 
msg_receive用于读取消息队列中的数据。 
msg_remove_queue ( resource $queue ) 
msg_remove_queue用于销毁一个队列。

示例代码_1只是展示了PHP操作消息队列函数的应用。下面的代码具体描述了进程间通信的场景
<?php 
$message_queue_key = ftok(__FILE__, 'a'); 
$message_queue = msg_get_queue($message_queue_key, 0666); 
$pids = array(); 
for ($i = 0; $i < 5; $i++) { 
//创建子进程 
$pids[$i] = pcntl_fork(); 
if ($pids[$i]) { 
echo "No.$i child process was created, the pid is $pids[$i]\r\n"; 
} elseif ($pids[$i] == 0) { 
$pid = posix_getpid(); 
echo "process.$pid is writing now\r\n"; 
msg_send($message_queue, 1, "this is process.$pid's data\r\n"); 
posix_kill($pid, SIGTERM); 
} 
} 
do { 
msg_receive($message_queue, 0, $message_type, 1024, $message, true, MSG_IPC_NOWAIT); 
echo $message; 
//需要判断队列是否为空,如果为空就退出 
//break; 
} while(true) 
?>

运行结果为:
No.0 child process was created, the pid is 5249 
No.1 child process was created, the pid is 5250 
No.2 child process was created, the pid is 5251 
No.3 child process was created, the pid is 5252 
No.4 child process was created, the pid is 5253 
process.5251 is writing now 
this is process.5251's data 
process.5253 is writing now 
process.5252 is writing now 
process.5250 is writing now 
this is process.5253's data 
this is process.5252's data 
this is process.5250's data 
process.5249 is writing now 
this is process.5249's data

这段程序每次的运行结果都会不同,这正说明了多进程的异步性。从结果也能看出消息队列FIFO特性。
以上便是我研究的一点心得。接下来将会继续研究PHP利用信号、socket等进行进程间通信的方法。
PHP 相关文章推荐
在WAMP环境下搭建ZendDebugger php调试工具的方法
Jul 18 PHP
php数组函数序列之array_keys() - 获取数组键名
Oct 30 PHP
解析crontab php自动运行的方法
Jun 24 PHP
解析数组非数字键名引号的必要性
Aug 09 PHP
php循环创建目录示例分享(php创建多级目录)
Mar 04 PHP
一个不易被发现的PHP后门代码解析
Jul 05 PHP
PHP正则表达式入门教程(推荐)
May 18 PHP
PHP+Ajax异步带进度条上传文件实例
Nov 01 PHP
php删除数组指定元素实现代码
May 03 PHP
PHP序列化的四种实现方法与横向对比
Nov 29 PHP
PHP经典设计模式之依赖注入定义与用法详解
May 21 PHP
THINKPHP-Apache服务器中使用Alias虚拟目录URL重写 隐藏index.php
Mar 09 PHP
php抓取页面与代码解析 推荐
Jul 23 #PHP
由php的call_user_func传reference引发的思考
Jul 23 #PHP
Google Voice 短信发送接口PHP开源版(2010.5更新)
Jul 22 #PHP
PHP 飞信好友免费短信API接口开源版
Jul 22 #PHP
PHP计划任务之关闭浏览器后仍然继续执行的函数
Jul 22 #PHP
PHP垃圾回收机制简单说明
Jul 22 #PHP
PHP多线程抓取网页实现代码
Jul 22 #PHP
You might like
用PHP的ob_start();控制您的浏览器cache!
2007/02/14 PHP
JS异常处理try..catch语句的作用和实例
2014/05/05 PHP
php打包压缩文件之ZipArchive方法用法分析
2016/04/30 PHP
PHP中使用foreach()遍历二维数组的简单实例
2016/06/13 PHP
php版微信公众平台实现预约提交后发送email的方法
2016/09/26 PHP
Jquery操作Select 简单方便 一个js插件搞定
2009/11/12 Javascript
ExtJs中gridpanel分组后组名排序实例代码
2013/12/02 Javascript
JS获取图片高度宽度的方法分享
2015/04/17 Javascript
第一次接触神奇的Bootstrap网格系统
2016/07/27 Javascript
jQuery Ajax使用FormData对象上传文件的方法
2016/09/07 Javascript
基于jQuery实现的幻灯图片切换
2016/12/02 Javascript
BootStrap中
2016/12/10 Javascript
浅谈Node.js轻量级Web框架Express4.x使用指南
2017/05/03 Javascript
ES6正则表达式的一些新功能总结
2017/05/09 Javascript
vue项目开发中setTimeout等定时器的管理问题
2018/09/13 Javascript
微信小程序--获取用户地理位置名称(无须用户授权)的方法
2019/04/29 Javascript
微信小程序实现拼图小游戏
2020/10/22 Javascript
Python实现购物系统(示例讲解)
2017/09/13 Python
Django+uni-app实现数据通信中的请求跨域的示例代码
2019/10/12 Python
python TK库简单应用(实时显示子进程输出)
2019/10/29 Python
Python性能分析工具Profile使用实例
2019/11/19 Python
python:动态路由的Flask程序代码
2019/11/22 Python
Python3加密解密库Crypto的RSA加解密和签名/验签实现方法实例
2020/02/11 Python
全球知名旅游社区法国站点:TripAdvisor法国
2016/08/03 全球购物
MADE荷兰:提供原创设计师家具
2018/04/03 全球购物
澳大利亚领先的内衣店:Bendon Lingerie澳大利亚
2020/05/15 全球购物
临床医学大学生求职信
2013/09/28 职场文书
办公室副主任岗位职责
2013/11/25 职场文书
学生会竞选演讲稿
2014/04/24 职场文书
统计专业自荐书
2014/07/06 职场文书
六查六看自检自查剖析材料
2014/10/14 职场文书
2014村书记党建工作汇报材料
2014/11/02 职场文书
html实现随机点名器的示例代码
2021/04/02 Javascript
虚拟机linux端mysql数据库无法远程访问的解决办法
2021/05/26 MySQL
详解如何用Python实现感知器算法
2021/06/18 Python
本地搭建minio文件服务器(使用bat脚本启动)的方法
2022/07/15 Servers