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 相关文章推荐
WINXP下apache+php4+mysql
Nov 25 PHP
fleaphp下不确定的多条件查询的巧妙解决方法
Sep 11 PHP
PHP 根据IP地址控制访问的代码
Apr 22 PHP
json的键名为数字时的调用方式(示例代码)
Nov 15 PHP
php页码形式分页函数支持静态化地址及ajax分页
Mar 28 PHP
ThinkPHP页面跳转success与error方法概述
Jun 25 PHP
php实现约瑟夫问题的方法小结
Mar 23 PHP
PHP中判断文件存在使用is_file还是file_exists?
Apr 03 PHP
php实现简单的MVC框架实例
Sep 23 PHP
前端必学之PHP语法基础
Jan 01 PHP
PHP读MYSQL中文乱码的快速解决方法
Oct 01 PHP
php7安装mongoDB扩展的方法分析
Aug 02 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
解决了Ajax、MySQL 和 Zend Framework 的乱码问题
2009/03/03 PHP
PHP的邮件群发系统phplist配置方法详细总结
2016/03/30 PHP
laravel5.5添加echarts实现画图功能的方法
2019/10/09 PHP
Laravel5.5 动态切换多语言的操作方式
2019/10/25 PHP
javascript 面向对象全新理练之原型继承
2009/12/03 Javascript
使用jQuery Ajax功能时需要注意的一个问题(内存溢出)
2012/05/30 Javascript
让页面上两个div中的滚动条(滑块)同步运动示例
2013/08/07 Javascript
详解JavaScript语法对{}处理的坑爹之处
2014/06/05 Javascript
jquery中radio checked问题
2015/03/16 Javascript
老生常谈Bootstrap媒体对象
2017/07/06 Javascript
jQuery实现菜单栏导航效果
2017/08/15 jQuery
JS实现可切换图片的幻灯切换效果示例
2019/05/24 Javascript
vue+ts下对axios的封装实现
2020/02/18 Javascript
python里将list中元素依次向前移动一位
2014/09/12 Python
python检测某个变量是否有定义的方法
2015/05/20 Python
Python 3.x 连接数据库示例(pymysql 方式)
2017/01/19 Python
python中requests库session对象的妙用详解
2017/10/30 Python
python对文件目录的操作方法实例总结
2019/06/24 Python
python3.x+pyqt5实现主窗口状态栏里(嵌入)显示进度条功能
2019/07/04 Python
基于python判断目录或者文件代码实例
2019/11/29 Python
python 中值滤波,椒盐去噪,图片增强实例
2019/12/18 Python
Python流程控制常用工具详解
2020/02/24 Python
浅析python表达式4+0.5值的数据类型
2020/02/26 Python
Django REST framwork的权限验证实例
2020/04/02 Python
python3 使用openpyxl将mysql数据写入xlsx的操作
2020/05/15 Python
Raleigh兰令自行车美国官网:英国凤头牌自行车
2018/01/08 全球购物
描述JSP和Servlet的区别、共同点、各自应用的范围
2012/10/02 面试题
党员个人思想汇报
2013/12/28 职场文书
乌鸦喝水教学反思
2014/02/07 职场文书
单位实习工作证明怎么写
2014/11/02 职场文书
2015年新农村建设工作总结
2015/05/22 职场文书
教研活动主持词
2015/07/03 职场文书
导游词之包公祠
2019/11/25 职场文书
解决golang 关于全局变量的坑
2021/05/06 Golang
Mysql中调试存储过程最简单的方法
2021/06/30 MySQL
mysql5.5中文乱码问题解决的有用方法
2022/05/30 MySQL