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 相关文章推荐
php session和cookie使用说明
Apr 07 PHP
php中使用preg_match_all匹配文章中的图片
Feb 06 PHP
PHP 如何获取二维数组中某个key的集合
Jun 03 PHP
PHP实现支持GET,POST,Multipart/form-data的HTTP请求类
Sep 24 PHP
PHP实现获取域名的方法小结
Nov 05 PHP
微信公众平台开发实现2048游戏的方法
Apr 15 PHP
PHP Reflection API详解
May 12 PHP
PHP中strncmp()函数比较两个字符串前2个字符是否相等的方法
Jan 07 PHP
PHP入门教程之面向对象基本概念实例分析
Sep 11 PHP
PHP+MYSQL实现读写分离简单实战
Mar 13 PHP
PHP经典实用正则表达式小结
May 04 PHP
PHP实现的最大正向匹配算法示例
Dec 19 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面向对象全攻略 (二) 实例化对象 使用对象成员
2009/09/30 PHP
通过PHP的内置函数,通过DES算法对数据加密和解密
2012/06/21 PHP
详解PHP实现执行定时任务
2015/12/21 PHP
PHP基于单例模式实现的mysql类
2016/01/09 PHP
PHP常见的序列化与反序列化操作实例分析
2019/10/28 PHP
ExtJS的FieldSet的column列布局
2009/11/20 Javascript
关于图片的预加载过程中隐藏未知的
2012/12/19 Javascript
javascript中Object使用详解
2015/01/26 Javascript
详解JavaScript中setSeconds()方法的使用
2015/06/11 Javascript
jquery实现Slide Out Navigation滑出式菜单效果代码
2015/09/07 Javascript
Js+Ajax,Get和Post在使用上的区别小结
2016/06/08 Javascript
浅谈JavaScript对象的创建方式
2016/06/13 Javascript
jquery实现跳到底部,回到顶部效果的简单实例(类似锚)
2016/07/10 Javascript
在Web关闭页面时发送Ajax请求的实现方法
2019/03/07 Javascript
vue动画效果实现方法示例
2019/03/18 Javascript
vuex Module将 store 分割成模块的操作
2020/12/07 Vue.js
vue项目配置 webpack-obfuscator 进行代码加密混淆的实现
2021/02/26 Vue.js
简单介绍Python中的几种数据类型
2016/01/02 Python
django 常用orm操作详解
2017/09/13 Python
Django中的AutoField字段使用
2020/05/18 Python
Python Excel vlookup函数实现过程解析
2020/06/22 Python
python3爬虫中多线程的优势总结
2020/11/24 Python
python中的列表和元组区别分析
2020/12/30 Python
CSS3使用border-radius属性制作圆角
2014/12/22 HTML / CSS
英国现代绅士品牌:Hackett
2017/12/17 全球购物
英国高级健康和美容产品零售商:Life and Looks
2019/08/01 全球购物
Fabletics官网:美国运动服饰品牌,由好莱坞女演员凯特·哈德森创立
2019/10/19 全球购物
创业计划书中要认真思考的问题
2013/12/28 职场文书
家长会演讲稿
2014/04/26 职场文书
煤矿开采专业求职信
2014/07/08 职场文书
课程设计的心得体会
2014/09/03 职场文书
高中生期中考试失利检讨书
2014/10/23 职场文书
党的群众路线教育实践活动个人对照检查材料(教师)
2014/11/04 职场文书
html form表单基础入门案例讲解
2021/07/21 HTML / CSS
Java实现二分搜索树的示例代码
2022/03/17 Java/Android
Meta增速拉垮,元宇宙难当重任
2022/04/29 数码科技