Linux进程通信之消息队列

Linux进程通信之IPC消息队列

首先消息队列是存放消息的队列,而队列则是一种先进先出的数据结构。

在PHP扩展中,封装了8个消息队列相关的函数,有 ftokmsg_get_queuemsg_queue_existsmsg_receivemsg_remove_queuemsg_sendmsg_set_queuemsg_stat_queue 具体的相关参数以及介绍,请查看PHP手册及相关文档 PHP手册之IPC

不同进程间消息队列通信

写进程demo21.php

//根据一个存在的文件和标识生成消息队列的key
$key = ftok('demo21.php','a');

//创建消息队列
$msgId = msg_get_queue($key);

//向消息队列中发送消息
msg_send($msgId,1,'test');

var_dump($msgId);

执行命令,查看结果,打印的是返回的消息队列id 在终端中输入 ipcs 查看是否创建并发送成功 可以看到上面插入了一条消息,可以反复重复以上命令,可以看到多条消息插入进行。如果有看的仔细的同学可能会有这样一个疑问,我明明写入的test是四个字节,为什么存入了11个字节,接下来我们使用strace -f -s 6550 php demo21.php 命令查看一下

通过执行上面的命令,我们可以看到,实际底层当中调用的是 msggetmsgsnd函数,并且也可以看到,实际存入的数据是经过PHP封装序列化过之后的数据,所以我们存入的命名是4个字节,实际显示的是11个字节的原因,当然,我们也可以在函数中禁用序列化

读进程 demo22.php

//根据一个存在的文件和标识生成消息队列的key
$key = ftok('demo21.php','a');

//创建消息队列
$msgId = msg_get_queue($key);

//接收消息队列消息
msg_receive($msgId,1,$type,1024,$message);


var_dump($message);

执行命令,查看返回结果,可以看到我们写入的数据 再次调用ipcs查看消息队列相关信息,发现数据已被取走并清零

父子进程消息队列通信

假设是子进程接收,父进程发送

$key = ftok('demo23.php','a');

//获取消息队列
$msgId = msg_get_queue($key);

//打印消息队列信息
print_r(msg_stat_queue($msgId));


$pid = pcntl_fork();

$i = 1 ;

//子进程
if(0==$pid)
{
    while (1){
        //接收消息队列信息
        msg_receive($msgId,0,$type,1024,$msg);

        echo $msg."\r\n";
    }

}


while (1){
    //发送队列
    msg_send($msgId,1,'test');
    sleep(3);
     //当发送五次后
    if($i++ ==5)
    {
        //杀死子进程
        posix_kill($pid,SIGKILL);
        break;
    }
}

//回收子进程
$pid = pcntl_wait($status);

//子进程回收成功
if($pid > 0)
{
    fprintf(STDOUT,"child procss exit ok pid=%d\r\n",$pid);
}

//清除消息队列
if(msg_remove_queue($msgId))
{
    fprintf(STDOUT,"queue exit ok\r\n");
}


执行命令,查看结果。可以看到上面打印的是队列的相关信息,如mode 是权限、qnum队列中有几条、qbytes 消息队列的最大限制等等,最终执行五次后,退出子进程并回收 执行pstree -ap 命令查看到是两个进程再执行 再次执行 ipcs 查看,发现只剩我们上面测试的那一个消息队列,本次运行的消息队列已经清除成功

注意

  • 当开启序列化时,如果发送的数据字节,小于接收数据的字节(msg_receive函数的第四个参数),那么数据就会反序列化失败,并抛出系统异常
  • 当序列化时,设置的接收字节小于发送的字节并设置为MSG_NOERROR(msg_receive函数的第七个参数)时,不会抛出系统异常并正常接收设置的字节数,舍弃其他字节数据
  • 当接收数据为非阻塞方式时,设置MSG_IPC_NOWAIT(msg_receive函数的第七个参数),系统会一直调用底层函数并返回失败,造成CPU资源浪费

北溟有鱼QAQ博客
请先登录后发表评论
  • 最新评论
  • 总共1条评论
北溟有鱼QAQ博客

Silence:大佬真棒

2021-09-07 15:35:06 回复