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 中执行排序与 MySQL 中排序
Apr 21 PHP
php数组函数序列之array_sum() - 计算数组元素值之和
Oct 29 PHP
PHP正则表达式替换站点关键字链接后空白的解决方法
Sep 16 PHP
php页面缓存方法小结
Jan 10 PHP
ThinkPHP3.2.2的插件控制器功能
Mar 05 PHP
10个php函数实用却不常见
Oct 13 PHP
PHP 输出缓冲控制(Output Control)详解
Aug 25 PHP
PHP经典算法集锦【经典收藏】
Sep 14 PHP
PHP实现广度优先搜索算法(BFS,Broad First Search)详解
Sep 16 PHP
PHP编程实现的TCP服务端和客户端功能示例
Apr 13 PHP
laradock环境docker-compose操作详解
Jul 29 PHP
Thinkphp5框架异常处理操作实例分析
Jun 03 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+MySQL插入操作实例
2015/01/21 PHP
ThinkPHP3.2.2的插件控制器功能
2015/03/05 PHP
php使用memcoder将视频转成mp4格式的方法
2015/03/12 PHP
php 多继承的几种常见实现方法示例
2019/11/18 PHP
jQuery Validation实例代码 让验证变得如此容易
2010/10/18 Javascript
JS仿flash上传头像效果实现代码
2011/07/18 Javascript
JS识别浏览器类型(电脑浏览器和手机浏览器)
2016/11/18 Javascript
Bootstrap CSS组件之输入框组
2016/12/17 Javascript
d3.js中冷门却实用的内置函数总结
2017/02/04 Javascript
Angular实现跨域(搜索框的下拉列表)
2017/02/16 Javascript
webpack2.0配置postcss-loader的方法
2017/08/17 Javascript
3种vue组件的书写形式
2017/11/29 Javascript
200行代码实现blockchain 区块链实例详解
2018/03/14 Javascript
深入浅析Vue中的 computed 和 watch
2018/06/06 Javascript
jsonp跨域及实现百度首页联想功能的方法
2018/08/30 Javascript
Vue实现固定定位图标滑动隐藏效果
2019/05/30 Javascript
对vuex中getters计算过滤操作详解
2019/11/06 Javascript
JavaScript如何处理移动端拍摄图片旋转问题
2019/11/16 Javascript
vue.js iview打包上线后字体图标不显示解决办法
2020/01/20 Javascript
Python Sql数据库增删改查操作简单封装
2016/04/18 Python
Python 生成一个从0到n个数字的列表4种方法小结
2019/11/28 Python
Python读取文件内容为字符串的方法(多种方法详解)
2020/03/04 Python
Python 生成VOC格式的标签实例
2020/03/10 Python
基于Django OneToOneField和ForeignKey的区别详解
2020/03/30 Python
Python中如何引入第三方模块
2020/05/27 Python
python用tkinter实现一个简易能进行随机点名的界面
2020/09/27 Python
css3翻牌翻数字的示例代码
2020/02/07 HTML / CSS
购买限量版收藏品、珠宝和礼品:Bradford Exchange
2016/09/23 全球购物
美特斯邦威官方商城:邦购网
2016/10/13 全球购物
意大利拉斐尔时尚购物网:Raffaello Network(支持中文)
2018/11/09 全球购物
XD健身器材:Kevlar球、Crossfit健身球
2019/03/26 全球购物
现代化办公人员工作的自我评价
2013/10/16 职场文书
自我评价是什么
2014/01/04 职场文书
红领巾心向党演讲稿
2014/09/10 职场文书
Matlab如何实现矩阵复制扩充
2021/06/02 Python
Python 发送SMTP邮件的简单教程
2021/06/24 Python