PHP下操作Linux消息队列完成进程间通信的方法_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等进行进程间通信的方法。

时间: 2024-08-22 15:15:59

PHP下操作Linux消息队列完成进程间通信的方法_php技巧的相关文章

Linux安装配置php环境的方法_php技巧

本文实例讲述了Linux安装配置php环境的方法.分享给大家供大家参考,具体如下: 1.获取安装文件: http://www.php.net/downloads.php php-5.3.8.tar.gz 获取安装php需要的支持文件:http://download.csdn.net/download/netlong339/1351852 libxml2-2.6.32.tar.gz 2.安装libxml2 复制代码 代码如下: tar zxvf libxml2-2.6.32.tar.gz cd l

php下HTTP Response中的Chunked编码实现方法_php技巧

进行Chunked编码传输的HTTP Response会在消息头部设置: Transfer-Encoding: chunked 表示Content Body将用Chunked编码传输内容. Chunked编码使用若干个Chunk串连而成,由一个标明长度为0的chunk标示结束.每个Chunk分为头部和正文两部分,头部内容指定下一段正文的字符总数(十六进制的数字)和数量单位(一般不写),正文部分就是指定长度的实际内容,两部分之间用回车换行(CRLF)隔开.在最后一个长度为0的Chunk中的内容是称

PHP数组操作——获取数组最后一个值的方法_php技巧

<?php $array=array(1,2,3,4,5); echo $array[count($array)-1];//计算数组长度,然后获取数组最后一个元素,如果数组中最后一个元素含有非数字键名,结果可能跟预期不符合 //适用于键名为数字的数组 echo '<br>'; echo end($array);//将数组的内部指针指向最后一个单元,适用于所有数组 echo '<br>'; rsort($array);//对数组逆向排序,如果数组中含有字母或汉字,结果可能不符合

Linux编译升级php的详细方法_php技巧

服务器环境:CentOS – 5.4php升级:5.4.14 - 5.5.0升级心得:比较顺利,但是有一点需要说明:eaccelerator无法兼容php5.5.0,好在php在5.5.0默认提供了Zend OPcache,所以一直习惯eaccelerator的朋友如果要升级到php5.5.0的话,可能要暂时和eaccelerator说bye bye了.1.安装php5.5.0下载php安装包:http://www.php.net/get/php-5.5.0.tar.gz/from/a/mirr

虚拟机-windows下操作linux的软件

问题描述 windows下操作linux的软件 20C 我是一个刚刚实习的码农.公司要求使用linux,我用的vmware,装了一个ubuntu14.04.由于公司给配置的电脑内存小,虚拟机运行起来,加上有的时候内外一起操作导致整个电脑就要爆炸了.于是,我想了个办法,利用ssh和putty实现了在windows下操作linux的终端.但是这编程用的软件是Sublime text2,我只能使用终端,接下来还要使用chrome,这要是还要到虚拟机里去操作的话那还是一个字卡.我听我的menager讲,

linux 消息队列-Linux消息队列使用时,msgsnd()一直不能通过,大家帮忙看看!

问题描述 Linux消息队列使用时,msgsnd()一直不能通过,大家帮忙看看! #include #include #include #include #include #include #include #include #define QUEUE1 100 #define QUEUE2 101 /* redefine struct msg_buf */ struct msgmbuf{ //msg type long mtype; //the field used to store URL

如何使用Jedis操作Redis消息队列

资源链接 Jedis的jar包Commons-io的jar包 使用方法 代码样例如下,使用前,注意打开redis的server程序. 代码样例 package RedisExample; import redis.clients.jedis.Jedis; public class TestRedis { public static void main(String[] args) { Jedis redis = new Jedis("localhost"); // SimpleExam

phpredis提高消息队列的实时性方法(推荐)_Redis

数据库存贮都用list形式 要存2个队列 1个用作消息队列保存到数据 还有个 就是用来实时读取数据在redis $redis->lpush($queenkey, json_encode($array)); $redis->lpush($listkey, json_encode($array)); /*消息队列实例*/ public function insertinfo() { $infos = array('info1' => mt_rand(10,100), 'info2' =>

vc操作微软消息队列的方法

定义 IMSMQQueuePtr qDest; // Represents Destination Queue IMSMQQueueInfoPtr qInfo; //Represents an open instance of the destination queue IMSMQQueueInfoPtr qRead; IMSMQMessagePtr qMsg; //Represents the message 初始化 qDest = NULL; CoInitialize(NULL); try{