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 相关文章推荐
打造计数器DIY三步曲(上)
Oct 09 PHP
用php+mysql一个名片库程序
Oct 09 PHP
dede3.1分页文字采集过滤规则详说(图文教程)
Apr 03 PHP
php中cookie的作用域
Mar 27 PHP
PHP 面向对象详解
Sep 13 PHP
PHP中使用CURL模拟登录并获取数据实例
Jul 01 PHP
ThinkPHP2.x防范XSS跨站攻击的方法
Sep 25 PHP
PHP的APC模块实现上传进度条
Oct 27 PHP
Yii列表定义与使用分页方法小结(3种方法)
Jul 15 PHP
关于PHP定时发送服务的解决办法
Apr 23 PHP
PHP网页安全认证的实例详解
Sep 28 PHP
PHP 实现链式操作
Mar 09 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 mcrypt可逆加密算法分析
2011/07/19 PHP
php实现在多维数组中查找特定value的方法
2015/07/29 PHP
php计算年龄精准到年月日
2015/11/17 PHP
PHP对象相关知识总结
2017/04/09 PHP
PHP大文件分割上传 PHP分片上传
2017/08/28 PHP
详解PHP队列的实现
2019/03/14 PHP
jQuery使用andSelf()来包含之前的选择集
2014/05/19 Javascript
jQuery数据缓存用法分析
2015/02/20 Javascript
如何使用jquery修改css中带有!important的样式属性
2016/04/28 Javascript
EasyUI加载完Html内容样式渲染完成后显示
2016/07/25 Javascript
ES6新特性六:promise对象实例详解
2017/04/21 Javascript
AngularJS的脏检查深入分析
2017/04/22 Javascript
Node.js学习之TCP/IP数据通讯(实例讲解)
2017/10/11 Javascript
AngularJS使用$http配置对象方式与服务端交互方法
2018/08/13 Javascript
vscode配置vue下的es6规范自动格式化详解
2019/03/20 Javascript
layui复选框的全选与取消实现方法
2019/09/02 Javascript
Python3处理文件中每个词的方法
2015/05/22 Python
python 设置文件编码格式的实现方法
2017/12/21 Python
Django处理文件上传File Uploads的实例
2018/05/28 Python
pycharm 将django中多个app放到同个文件夹apps的处理方法
2018/05/30 Python
解决安装python3.7.4报错Can''t connect to HTTPS URL because the SSL module is not available
2019/07/31 Python
python实现FTP循环上传文件
2020/03/20 Python
用Python制作mini翻译器的实现示例
2020/08/17 Python
css3个性化字体_动力节点Java学院整理
2017/07/12 HTML / CSS
使用css3背景渐变中的透明度来设置不同颜色的背景渐变
2014/03/31 HTML / CSS
CSS3 按钮边框动画的实现
2020/11/12 HTML / CSS
美国最大婚纱连锁店运营商:David’s Bridal
2019/03/12 全球购物
销售活动策划方案
2014/08/26 职场文书
综治工作心得体会
2014/09/11 职场文书
中小学校园安全广播稿
2014/09/29 职场文书
会议欢迎词
2015/01/23 职场文书
世界水日宣传活动总结
2015/02/09 职场文书
《和时间赛跑》读后感3篇
2019/12/16 职场文书
HTML速写之Emmet语法规则的实现
2021/04/07 HTML / CSS
浅谈Python类的单继承相关知识
2021/05/12 Python
python神经网络学习 使用Keras进行回归运算
2022/05/04 Python