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 相关文章推荐
在任意字符集下正常显示网页的方法一
Apr 01 PHP
php反弹shell实现代码
Apr 22 PHP
PHP 日常开发小技巧
Sep 23 PHP
Php图像处理类代码分享
Jan 19 PHP
PHP中的错误处理、异常处理机制分析
May 07 PHP
php共享内存段示例分享
Jan 20 PHP
PHP实现使用优酷土豆视频地址获取swf播放器分享地址
Jun 05 PHP
PHP往XML中添加节点的方法
Mar 12 PHP
php使用simplexml_load_file加载XML文件并显示XML的方法
Mar 19 PHP
php提交post数组参数实例分析
Dec 17 PHP
微信公众平台开发教程⑥ 微信开发集成类的使用图文详解
Apr 10 PHP
PHP回调函数简单用法示例
May 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截取中文字符串的问题
2006/07/12 PHP
php checkbox复选框值的获取与checkbox默认值输出方法
2010/05/15 PHP
destoon后台网站设置变成空白的解决方法
2014/06/21 PHP
thinkPHP学习笔记之安装配置篇
2015/03/05 PHP
PHP  Yii清理缓存的实现方法
2016/11/10 PHP
微信公众平台开发(五) 天气预报功能开发
2016/12/03 PHP
php实现文件上传及头像预览功能
2017/01/15 PHP
在IIS下安装PHP扩展的方法(超简单)
2017/04/10 PHP
PHP的PDO预处理语句与存储过程
2019/01/27 PHP
tp5.1 框架join方法用法实例分析
2020/05/26 PHP
Javascript - HTML的request类
2007/01/09 Javascript
javascript判断单选框或复选框是否选中方法集锦
2007/04/04 Javascript
jquery图片上下tab切换效果
2011/03/18 Javascript
实例代码讲解jquery easyui动态tab页
2015/11/17 Javascript
JavaScript Split()方法
2015/12/18 Javascript
浅谈JavaScript for循环 闭包
2016/06/22 Javascript
浅谈 Vue 项目优化的方法
2017/12/16 Javascript
国内常用的js类库大全(CDN公共库)
2020/06/24 Javascript
[01:15:29]DOTA2上海特级锦标赛主赛事日 - 3 胜者组第二轮#2Secret VS EG第三局
2016/03/04 DOTA
Python生成验证码实例
2014/08/21 Python
Python多线程同步Lock、RLock、Semaphore、Event实例
2014/11/21 Python
对Python3中的input函数详解
2018/04/22 Python
python向已存在的excel中新增表,不覆盖原数据的实例
2018/05/02 Python
wxPython+Matplotlib绘制折线图表
2019/11/19 Python
解决python便携版无法直接运行py文件的问题
2020/09/01 Python
如何基于python实现年会抽奖工具
2020/10/20 Python
德国孕妇装和婴童服装网上商店:bellybutton
2018/04/12 全球购物
德国家具折扣店:POCO
2020/02/28 全球购物
介绍一下Linux文件的记录形式
2013/09/29 面试题
应届生法律顾问求职信
2013/11/19 职场文书
志愿者服务感言
2014/02/27 职场文书
电子信息工程专业求职信
2014/06/28 职场文书
软件工程毕业生自荐信
2014/07/04 职场文书
入团申请书格式
2019/06/20 职场文书
2019个人年度目标制定攻略!
2019/07/12 职场文书
导游词创作书写原则以及开场白技巧怎么学?
2019/09/25 职场文书