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制作静态网站的模板框架
Oct 09 PHP
PHP 如何向 MySQL 发送数据
Oct 09 PHP
PHP中的float类型使用说明
Jul 27 PHP
iis下php mail函数的sendmail配置方法(官方推荐)
Apr 25 PHP
PHP实现的连贯操作、链式操作实例
Jul 08 PHP
php实现微信公众平台账号自定义菜单类
Dec 02 PHP
CI(CodeIgniter)模型用法实例分析
Jan 20 PHP
php 的反射详解及示例代码
Aug 25 PHP
PHP用户注册邮件激活账户的实现代码
May 31 PHP
PHP基于redis计数器类定义与用法示例
Feb 08 PHP
laravel实现简单用户权限的示例代码
May 28 PHP
discuz论坛更换域名,详细文件修改步骤
Dec 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支持断点续传的源码
2010/05/16 PHP
使用ThinkPHP+Uploadify实现图片上传功能
2014/06/26 PHP
PHP bin2hex()函数基础实例讲解
2019/02/11 PHP
javascript一点特殊用法
2008/05/28 Javascript
33种Javascript 表格排序控件收集
2009/12/03 Javascript
Js 时间间隔计算的函数(间隔天数)
2011/11/15 Javascript
JQuery入门——用映射方式绑定不同事件应用示例
2013/02/05 Javascript
js Math 对象的方法
2013/09/01 Javascript
jsPDF生成pdf后在网页展示实例
2014/01/16 Javascript
javacript使用break内层跳出外层循环分析
2015/01/12 Javascript
javascript去除空格方法小结
2015/05/21 Javascript
详解Bootstrap创建表单的三种格式(一)
2016/01/04 Javascript
vue.js入门(3)——详解组件通信
2016/12/02 Javascript
JS产生随机数的用法小结
2016/12/10 Javascript
node.js 和HTML5开发本地桌面应用程序
2016/12/13 Javascript
Bootstrap CSS布局之表单
2016/12/17 Javascript
vue高德地图之玩转周边
2017/06/16 Javascript
小发现之浅谈location.search与location.hash的问题
2017/06/23 Javascript
Vue下路由History模式打包后页面空白的解决方法
2018/06/29 Javascript
JS使用Date对象实时显示当前系统时间简单示例
2018/08/23 Javascript
jquery.tagsinput.js实现记录checkbox勾选的顺序
2019/09/21 jQuery
浅谈Vue.js之初始化el以及数据的绑定说明
2019/11/14 Javascript
在NodeJs中使用node-schedule增加定时器任务的方法
2020/06/08 NodeJs
vue elementui tree 任意级别拖拽功能代码
2020/08/31 Javascript
vscode中的vue项目报错Property ‘xxx‘ does not exist on type ‘CombinedVueInstance<{ readyOnly...Vetur(2339)
2020/09/11 Javascript
使用JavaScript实现贪吃蛇游戏
2020/09/29 Javascript
Python实现按逗号分隔列表的方法
2018/10/23 Python
Python中base64与xml取值结合问题
2019/12/22 Python
Python中return函数返回值实例用法
2020/11/19 Python
以实惠的价格轻松租车,免费取消:Easyrentcars
2019/07/16 全球购物
斯洛伐克电子产品购物网站:DATART
2020/04/05 全球购物
如何将一个描述日期或日期/时间的字符串转换为一个Date对象
2015/10/13 面试题
应聘编辑自荐信范文
2014/03/12 职场文书
领导班子四风表现材料
2014/08/23 职场文书
未婚证明范本
2015/06/15 职场文书
Python djanjo之csrf防跨站攻击实验过程
2021/05/14 Python