PHP 进程间通信——消息队列

本文不涉及PHP基础库安装。详细安装说明,请参考官网,或期待后续博客分享。

1、消息队列函数准备

<?php
//生成一个消息队列的key
$msg_key = ftok(__FILE__, 'a');
//产生一个消息队列
$msg_queue = msg_get_queue($msg_key, 0666);
//检测一个队列是否存在 ,返回boolean值
$status = msg_queue_exists($msg_key);
//可以查看当前队列的一些详细信息
$message_queue_status =  msg_stat_queue($msg_queue);//将一条消息加入消息队列
msg_send($msg_queue, 1, "Hello, 1");
msg_send($msg_queue, 1, 'Hello, 2');
msg_send($msg_queue, 1, "Hello, 3");//从消息队列中读取一条消息。
msg_receive($msg_queue, 1, $message_type, 1024, $message1);
msg_receive($msg_queue, 1, $message_type, 1024, $message2);
msg_receive($msg_queue, 1, $message_type, 1024, $message3);//移除消息队列
msg_remove_queue($msg_queue);
echo $message1.PHP_EOL;
echo $message2.PHP_EOL;
echo $message3.PHP_EOL;/*** msg_send 有三个必选参数* resource $queue ,* int $msgtype ,* mixed $message** 第一个必须要是队列资源类型。resource(4) of type (sysvmsg queue)* 第二个参数是消息类型,一个整形,且必须大于0.* msg_send() sends a message of type msgtype (which MUST be greater than 0) to the message queue specified by queue.* 第三个参数。是要发送的信息。可以是字符串,也可以是数组。默认会被serialize.*//*** msg_receive 的参数比较多。必须要填的参数有5个。* resource $queue ,* int $desiredmsgtype ,* int &$msgtype ,* int $maxsize ,* mixed &$message** 其中$desiredmsgtype .经过测试和官网描述不符,暂不解释。** $msgtype 。这个是msg_send 中所选定的msg_type.这是一个引用参数。* The type of the message that was received will be stored in this parameter.** $maxsize。* The maximum size of message to be accepted is specified by the maxsize;* if the message in the queue is larger than this size the function will fail (unless you set flags as described below).* 这个参数声明的是一个最大的消息大小,如果超过则会报错。** $message.* 上文msg_send 发送的消息类型。*/

2、多进程通信实例

<?php
/*** 这段代码模拟了一个日常的任务。* 第一个父进程产生了一个子进程。子进程又作为父进程,产生10个子进程。* 可以简化为A -> B -> c,d,e... 等进程。* 作为A来说,只需要生产任务,然后交给B 来处理。B 则会将任务分配给10个子进程来进行处理。* *///设定脚本永不超时
set_time_limit(0);
$ftok = ftok(__FILE__, 'a');
$msg_queue = msg_get_queue($ftok);
$pidarr = [];//产生子进程
$pid = pcntl_fork();
if ($pid) {//父进程模拟生成一个特大的数组。$arr = range(1,100000);//将任务放进队里,让多个子进程并行处理foreach ($arr as $val) {$status = msg_send($msg_queue,1, $val);usleep(1000);}$pidarr[] = $pid;msg_remove_queue($msg_queue);
} else {//子进程收到任务后,fork10个子进程来处理任务。for ($i =0; $i<10; $i++) {$childpid = pcntl_fork();if ($childpid) {$pidarr[] = $childpid; //收集子进程processid} else {while (true) {msg_receive($msg_queue, 0, $msg_type, 1024, $message);if (!$message) exit(0);echo $message.PHP_EOL;usleep(1000);}}}
}//防止主进程先于子进程退出,形成僵尸进程
while (count($pidarr) > 0) {foreach ($pidarr as $key => $pid) {$status = pcntl_waitpid($pid, $status);if ($status == -1 || $status > 0) {unset($pidarr[$key]);}}sleep(1);
}
?>

以上的示例只是为了说明多进程通信的应用示例,并未在真实的项目中应用。为了示例方便,省略了很多的校验条件。但作为了解过程及原理来说,并不影响。 
在执行while 循环时候,必须要使用usleep(1000) 以上。否则CPU可能会被撑爆。 
以上的多进程通信,没有产生僵尸进程。得益于最后一段的while循环。 
其原理在于,父进程在每次循环的时候都检测子进程是否退出。如果退出,则父进程就会回收该子进程。并且将该进程从进程列表中删除。 
可以使用ps aux |grep process.php来查看当前产生的进程数量。 其中process.php 是运行的文件名 
效果如下:

[root@roverliang~]# ps aux |grep php
74:root      4163  9.3  2.2 243908 22844 pts/1    S+   17:42   0:00 php process.php
75:root      4164  0.0  0.3 229104  3924 pts/1    S+   17:42   0:00 php process.php
76:root      4165  1.3  0.4 229104  4124 pts/1    S+   17:42   0:00 php process.php
77:root      4166  1.3  0.4 229104  4124 pts/1    S+   17:42   0:00 php process.php
78:root      4167  1.0  0.4 229104  4124 pts/1    S+   17:42   0:00 php process.php
79:root      4168  1.3  0.4 229104  4124 pts/1    S+   17:42   0:00 php process.php
80:root      4169  1.3  0.4 229104  4124 pts/1    S+   17:42   0:00 php process.php
81:root      4170  1.3  0.4 229104  4124 pts/1    S+   17:42   0:00 php process.php
82:root      4171  1.3  0.4 229104  4124 pts/1    S+   17:42   0:00 php process.php
83:root      4172  1.3  0.4 229104  4124 pts/1    S+   17:42   0:00 php process.php
84:root      4173  1.3  0.4 229104  4124 pts/1    S+   17:42   0:00 php process.php
85:root      4174  1.3  0.4 229104  4124 pts/1    S+   17:42   0:00 php process.php

有疑问的话,可以共同讨论学习。博主也是刚学习这块,如果有什么不对的,希望能得到指点,共同提高。

PHP 进程间通信——消息队列(msg_queue)相关推荐

  1. Linux的进程间通信-消息队列

    Linux的进程间通信-消息队列 微博ID:orroz 微信公众号:Linux系统技术 前言 Linux系统给我们提供了一种可以发送格式化数据流的通信手段,这就是消息队列.使用消息队列无疑在某些场景的 ...

  2. 进程间通信——消息队列(Message queue)

    在Linux中,IPC消息队列是一个双向通信的全内存设计,即内核保证了读写顺序和数据同步,并且是性能比较好的先进先出的数据结构.消息队列的应用场景:比如异步任务处理,抢占式的数据分发,顺序缓存区等. ...

  3. Linux进程间通信--消息队列(Message queuing)

    今天我们来谈一谈Linux进程间通信的方式之一消息队列 我们先来看看关于消息队列的定义: 1.消息队列是消息的链表,存放在内核中并由消息队列标识符表示. 2.消息队列提供了一个从一个进程向另一个进程发 ...

  4. 【Linux系统编程】进程间通信--消息队列

    概述 消息队列提供了一种在两个不相关的进程之间传递数据的简单高效的方法,其特点如下: 1)消息队列可以实现消息的随机查询.消息不一定要以先进先出的次序读取,编程时可以按消息的类型读取. 2)消息队列允 ...

  5. 210127阶段三进程间通信-消息队列

    目录 一.学习的知识点 1 回顾 1.1 1.2 2 进程间通信 2.1进程间通信的目的 2.2 进程间通信 2.2.1 消息队列 二.上课没有听懂或者没有理解的地方 三.当天学习的收获 一.学习的知 ...

  6. Linux进程间通信——消息队列

    2019独角兽企业重金招聘Python工程师标准>>> 下面来说说如何用不用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章 ...

  7. 【进程】进程间通信----消息队列

    文章目录 1.消息队列 2.特性 3.实现接口 4.消息队列进程间通信 5.消息队列和命名管道的区别 5.1 相同之处 5.2 消息队列的优势 6.消息队列组织图 1.消息队列 消息队列,就是一个消息 ...

  8. linux 消息对lie_详解linux进程间通信-消息队列

    前言:前面讨论了信号.管道的进程间通信方式,接下来将讨论消息队列. 一.系统V IPC 三种系统V IPC:消息队列.信号量以及共享内存(共享存储器)之间有很多相似之处. 每个内核中的 I P C结构 ...

  9. Linux IPC 进程间通信——消息队列message

    消息队列是消息的连接表,存储在内核中.本实例主要实现消息队列方式进行进程间通信,接收端收到消息之后,立马转发给发送端:发送端发出消息之后,立马监听接收端回馈的消息,实现一个双向通信示例. 一.示例 发 ...

  10. linux进程间通信--消息队列相关函数(ftok)详解

    ftok 消息队列.信号灯.共享内存常用在Linux服务端编程的进程间通信环境中.而此三类编程函数在实际项目中都是用System V IPC函数实现的.System V IPC函数名称和说明如下表15 ...

最新文章

  1. android本地xml文件怎么打开,android 打开本地文件
  2. java 下载excel xlsx_JAVA Excel.xlsx 上传于下载
  3. LeetCode 17 电话号码的字母组合
  4. boost::exception的用法测试
  5. css3属性文字换行,CSS3让文本自动换行——word-break属性
  6. 使用C# (.NET Core) 实现命令设计模式 (Command Pattern)
  7. Error when loading the SDK:解决方案
  8. mysql恢复测试报告_mysqldump+mysqlbinlog恢复测试
  9. mysql5.7设置默认的字符集
  10. hbase 查询某列_hbase shell使用STARTROW、ENDROW、FILTER查出指定的列
  11. IE缓存文件提取器 视频,音频,图片一网打尽
  12. Java并发编程系列文章目录帖及源码
  13. Linux:TCP粘包问题的模拟实现以及解决方法
  14. 地理中经纬度的英文名称
  15. lwip---(五)以太网数据接收
  16. java++pdf文档合并_Java多个PDF文件合并成一个PDF文件-Go语言中文社区
  17. Unity5 Standard自发光材质无效解决方法
  18. 案例分享 | CEVA 使用 TensorFlow Lite 在边缘设备部署语音识别引擎及前端
  19. QTableView和QTableWidget的区别是什么?
  20. 【pytorch】torch2trt

热门文章

  1. plsql登录空白框_王者荣耀空白居中以及重复名的教程[含软件]
  2. linux下实用工具,Linux下的实用工具(持续更新)
  3. 7-4 谁会留下?规则如下:所有的学生绕成一圈,顺序排号,从第一个学生开始报数,凡是报到固定数字(例如 5)的都退出,直到只剩下一位学生游戏才中止。 (10 分)
  4. 软件功能测试怎么把关指标,软件测试方法经与验.doc
  5. 大工18春《c和c语言程序设计》,东大21春《高级语言程序设计基础》在线平时作业1题目及答案...
  6. vant 软键盘_H5页面 绝对定位元素被 软键盘弹出时顶起
  7. 牛客网SQL练习题(Mysql-8)
  8. usmssosetup 单点登录被禁用_单点登录系统,如果cookie被禁用了怎么办
  9. 跃迁 成为高手的技术
  10. JAVA常见的异常6_Java常见异常总结