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 相关文章推荐
apache2.2.4+mysql5.0.77+php5.2.8安装精简
Apr 29 PHP
php的array_multisort()使用方法介绍
May 16 PHP
php中防止SQL注入的最佳解决方法
Apr 25 PHP
php数组声明、遍历、数组全局变量使用小结
Jun 05 PHP
解析php中session的实现原理以及大网站应用应注意的问题
Jun 17 PHP
PHP利用REFERER根居访问来地址进行页面跳转
Sep 28 PHP
php5.4传引用时报错问题分析
Jan 22 PHP
php中的常用魔术方法汇总
Feb 14 PHP
postfixadmin忘记密码后的修改密码方法详解
Jul 20 PHP
php实现带读写分离功能的MySQL类完整实例
Jul 28 PHP
分享5个非常有用的Laravel Blade指令
May 30 PHP
PHP7.1实现的AES与RSA加密操作示例
Jun 15 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 imagegrabscreen和imagegrabwindow(截取网站缩略图)的实例代码
2013/11/07 PHP
php 解决substr()截取中文字符乱码问题
2016/07/18 PHP
JQuery 选择器、过滤器介绍
2011/02/14 Javascript
动态标签 悬停效果 延迟加载示例代码
2013/11/21 Javascript
jquery插件jquery倒计时插件分享
2013/12/27 Javascript
如何实现textarea里的不同文本显示不同颜色
2014/01/20 Javascript
js用typeof方法判断undefined类型
2014/07/15 Javascript
详细解密jsonp跨域请求
2015/04/15 Javascript
搞定immutable.js详细说明
2016/05/02 Javascript
js检测离开或刷新页面时表单数据是否更改的方法
2016/08/02 Javascript
JS正则替换掉小括号及内容的方法
2016/11/29 Javascript
nodejs个人博客开发第三步 载入页面
2017/04/12 NodeJs
详解ElementUI之表单验证、数据绑定、路由跳转
2017/06/21 Javascript
解决在vue+webpack开发中出现两个或多个菜单公用一个组件问题
2017/11/28 Javascript
在微信小程序中渲染HTML内容的方法示例
2018/09/28 Javascript
Bootstarp在pycharm中的安装及简单的使用方法
2019/04/19 Javascript
js神秘的电报密码 哈弗曼编码实现
2019/09/10 Javascript
[09:37]DOTA2卡尔工作室 英雄介绍圣堂刺客篇
2013/06/13 DOTA
Python修改MP3文件的方法
2015/06/15 Python
Python 元类实例解析
2018/04/04 Python
python 读取DICOM头文件的实例
2018/05/07 Python
超简单的Python HTTP服务
2019/07/22 Python
对python中的*args与**kwgs的含义与作用详解
2019/08/28 Python
Python类及获取对象属性方法解析
2020/06/15 Python
波兰运动鞋网上商店:e-Sporting
2018/02/16 全球购物
美国网上书店:Barnes & Noble
2018/08/15 全球购物
某公司面试题
2012/03/05 面试题
社区党员先进事迹
2014/01/22 职场文书
总经理司机岗位职责
2014/02/06 职场文书
信仰心得体会
2014/09/05 职场文书
大学生党性分析材料
2014/12/19 职场文书
材料采购员岗位职责
2015/04/03 职场文书
商务司机岗位职责
2015/04/10 职场文书
2015年惩防体系建设工作总结
2015/05/22 职场文书
Spring Security使用单点登录的权限功能
2022/04/03 Java/Android
Spring boot admin 服务监控利器详解
2022/08/05 Java/Android