PHP下操作Linux消息队列完成进程间通信的方法

yipeiwu_com5年前PHP代码库
关于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设计模式 Decorator(装饰模式)

复制代码 代码如下: <?php /** * 装饰模式 * * 动态的给一个对象添加一些额外的职责,就扩展功能而言比生成子类方式更为灵活 */ header("Content-ty...

php 获取页面中指定内容的实现类

功能: 1.获取内容中的url,email,image。 2.替换内容中的url,email,image。 url:<a href="url">xxx</a> e...

当前比较流行的两款PHP加密、解密工具Zend Guard和iconCube介绍

当前比较流行的两款PHP加密、解密工具Zend Guard和iconCube介绍

当前市场上较流行的对PHP进行上述加密授权的软件主要有二种: (1)Zend公司的ZendGuard。 (2)ionCube公司的ionCube PHP Encode。 ZendGuar...

php一维二维数组键排序方法实例总结

本文实例总结了php一维二维数组键排序方法。分享给大家供大家参考。具体方法如下: 在php中数组排序一直是一个老生常谈的问题,下面我们来集中讲一下关于在php中一维数组与二维数组排序的实...

PHP编程实现脚本异步执行的方法

本文实例讲述了PHP编程实现脚本异步执行的方法。分享给大家供大家参考,具体如下: php语言得用fsockopen()函数,实现脚本异步运行,代码如下 异步请求函数(用debug参数若为...