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 相关文章推荐
实时抓取YAHOO股票报价的代码
Oct 09 PHP
用PHP和ACCESS写聊天室(八)
Oct 09 PHP
php递归列出所有文件和目录的代码
Sep 10 PHP
php ob_flush,flush在ie中缓冲无效的解决方法
May 09 PHP
解析yahoo邮件用phpmailer发送的实例
Jun 24 PHP
PHP URL参数获取方式的四种例子
Feb 28 PHP
php警告Creating default object from empty value 问题的解决方法
Apr 02 PHP
php json转换成数组形式代码分享
Nov 10 PHP
php中静态类与静态变量用法的区别分析
Jan 15 PHP
PHP四种基本排序算法示例
Apr 09 PHP
WIN8.1下搭建PHP5.6环境
Apr 29 PHP
php函数式编程简单示例
Aug 08 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实现memcache缓存示例讲解
2013/12/04 PHP
php通过数组实现多条件查询实现方法(字符串分割)
2014/05/06 PHP
php实现httpRequest的方法
2015/03/13 PHP
PHP实现的解汉诺塔问题算法示例
2018/08/06 PHP
JS实现浏览器菜单命令
2006/09/05 Javascript
jquery阻止冒泡事件使用模拟事件
2013/09/06 Javascript
js禁止页面使用右键(简单示例代码)
2013/11/13 Javascript
js跳转页面方法总结
2014/01/29 Javascript
浅谈JavaScript正则表达式分组匹配
2015/04/10 Javascript
自己编写的支持Ajax验证的JS表单验证插件
2015/05/15 Javascript
JS验证邮件地址格式方法小结
2015/12/01 Javascript
基于JS代码实现当鼠标悬停表格上显示这一格的全部内容
2016/06/12 Javascript
jQuery事件委托之Safari
2016/07/05 Javascript
使用gulp搭建本地服务器并实现模拟ajax
2017/04/05 Javascript
nodejs socket实现的服务端和客户端功能示例
2017/06/02 NodeJs
vue上传图片组件编写代码
2017/07/26 Javascript
Node.js 的 GC 机制详解
2019/06/03 Javascript
vue项目中常见问题及解决方案(推荐)
2019/10/21 Javascript
微信小程序实现自定义底部导航
2020/11/18 Javascript
Flask之flask-session的具体使用
2018/07/26 Python
Python爬虫之UserAgent的使用实例
2019/02/21 Python
keras.layer.input()用法说明
2020/06/16 Python
一文带你了解Python 四种常见基础爬虫方法介绍
2020/12/04 Python
详解Java中一维、二维数组在内存中的结构
2021/02/11 Python
matplotlib部件之套索Lasso的使用
2021/02/24 Python
社区八一活动方案
2014/02/03 职场文书
大班开学家长寄语
2014/04/04 职场文书
党员干部廉洁承诺书
2014/05/28 职场文书
护士个人总结范文
2015/02/13 职场文书
最感人的道歉情书
2015/05/12 职场文书
反邪教观后感
2015/06/11 职场文书
廉洁自律证明
2015/06/24 职场文书
2016年暑假家长对孩子评语
2015/12/01 职场文书
redis通过6379端口无法连接服务器(redis-server.exe闪退)
2021/05/08 Redis
python 实现两个变量值进行交换的n种操作
2021/06/02 Python
Python使用openpyxl批量处理数据
2021/06/23 Python