知识准备:
ftok ( string $pathname , string $proj ) : int
Convert a pathname and a project identifier to a System V IPC key
把一个路径和标识符转换成IPC的key
msg_get_queue ( int $key [, int $perms = 0666 ] ) : resource
根据传入的键创建或返回一个消息队列的引用
getmypid ( void ) : int
获取当前PHP进程ID
msg_send ( resource $queue , int $msgtype , mixed $message [, bool $serialize = TRUE [, bool $blocking = TRUE [, int &$errorcode ]]] ) : bool
msg_send()向指定的消息队列发送msgtype类型的消息(该类型必须大于0)
参数1: resource $queue 要写入的消息队列资源
参数2 int $msgtype 要写入的消息队列的消息类型
参数3: mixed $message 要写入消息队列的消息
参数4: bool $serialize 是否序列化消息
参数5: bool $blocking 是否阻塞
msg_receive ( resource $queue , int $desiredmsgtype , int &$msgtype , int $maxsize , mixed &$message [, bool $unserialize = TRUE [, int $flags = 0 [, int &$errorcode ]]] ) : bool
msg_receive()向指定的消息队列读取消息
参数1: resource $queue 要读取的消息队列资源
参数2 int $desiredmsgtype 要读取的消息队列的消息类型, 如果为0则可以读取msg_send以任意$msgtype发送的消息
参数3: int &$msgtype 读取的消息类型会保存到该参数中
参数4: int $maxsize 以多大的字节数读取消息
参数5: mixed &$message 读取的消息会保存到该参数中
msg_remove_queue ( resource $queue ) : bool
销毁消息队列
pcntl_wait()
阻塞当前的进程直到子进程退出, 父进程回收子进程的资源, 防止产生僵尸进程
代码:
<?php
echo '父进程ID: ' . posix_getpid() . PHP_EOL;
// 创建消息队列
$msg_key = ftok(__FILE__, 'a');
$msg_queue = msg_get_queue($msg_key, 0666);
$pid = pcntl_fork();
switch ($pid) {
case -1:
die('fork failed');
break;
case 0:
msg_send($msg_queue, 1, 'child: ' . getmypid() . PHP_EOL);
exit;
break;
default:
// 父进程阻塞, 直到子进程退出, 确保子进程已经往消息队列中发送了消息
pcntl_wait($status);
msg_receive($msg_queue, 0, $message_type, 1024, $message, TRUE, MSG_IPC_NOWAIT);
echo 'msgtype: ' . $message_type . ' message: ' . $message;
msg_remove_queue($msg_queue);
break;
}
运行结果:
[root@e2963c647c8b www]# php queue.php
父进程ID: 1056
msgtype: 1 message: child: 1057