简介:这是在php中使用UNIX System V IPC机制共享应用程序数据的详细页面,介绍了和php,有关的知识、技巧、经验,和一些php源码等。
class='pingjiaF' frameborder='0' src='http://biancheng.dnbcw.info/pingjia.php?id=340850' scrolling='no'>UNIX System V IPC 主要用于进程间通信,主要有3种机制
1.消息队列
2.信号量
3.共享内存
更加详细的介绍可以参考
使用 UNIX System V IPC 机制共享应用程序数据
System V IPC指南
下面介绍在php中如何使用上文提到的3种IPC机制来共享应用程序数据
编译php时,加入编译参数
--enable-pcntl
--enable-sysvmsg
--enable-sysvshm
--enable-shmop
注意:以下脚本只能运行在php cli模式下
消息队列 ipc_msg.php
$key = ftok('ipc_msg.php', 'l');
// 生成一个队列id,供父子进程使用
$queue_id = msg_get_queue($key);
// 派生一个子进程
$pid = pcntl_fork();
$type = 1;
if ($pid == -1) {
// 出错退出
exit(1);
} else if ($pid > 0) {
// 父进程发送消息到队列
for ($i = 1; $i <= 10; $i++) {
msg_send($queue_id, $type, "msg [{$i}]: Hi, Mr.{$i}\n\n");
echo "send msg {$i}:",var_export(msg_stat_queue($queue_id)),"\n\n";
}
pcntl_waitpid($pid, $status);
} else {
// 子进程监听队列,有消息到达就显示出来
while (true) {
$queueInfo = msg_stat_queue($queue_id);
$queueNum = $queueInfo['msg_qnum'];
if ($queueNum == 0) {
sleep(5);
continue;
}
$result = msg_receive($queue_id, 0, $msgtype, 1000, $message);
echo $message;
}
}
信号量 ipc_sem.php
$key = ftok('ipc_sem.php', 's');
// 同时最多只能有一个进程进入临界区
$sem_id = sem_get($key, 1);
echo "欢迎来到公共厕所,本厕所只能容纳一个人\n\n";
// 派生子进程
$pid = pcntl_fork();
if ($pid == -1) {
exit(1);
} else if ($pid > 0) {
// 父进程
$name = '爸爸';
} else {
// 子进程
$name = '儿子';
}
echo "我是{$name},我要上厕所\n";
sem_acquire($sem_id);
// 原子操作开始
echo "我是{$name},我在厕所里,外面的人慢慢等吧\n";
sleep(10);
echo "我是{$name},我离开了厕所\n";
// 原子操作结束
sem_release($sem_id);
if ($pid > 0) {
pcntl_waitpid($pid, $status);
sem_remove($sem_id);
}
共享内存 ipc_shm.php
$key = ftok('ipc_shm.php', 'h');
$msg = "这是父进程写入的数据\n";
$len = strlen($msg);
// 创建一块指定大小的共享内存
$shm_id = shmop_open($key, 'c', 0644, $len);
$pid = pcntl_fork();
if ($pid == -1) {
exit(1);
} else if ($pid > 0) {
// 父进程,往共享内存中写数据
shmop_write($shm_id, $msg, 0);
pcntl_waitpid($pid, $status);
shmop_close($shm_id);
} else {
// 子进程,读取共享内存中的数据
sleep(1);
$data = shmop_read($shm_id, 0, $len);
echo $data;
}