push msg php_php进程通信-消息队列
php多进程通信,有各种各样的方法(进程信号,消息队列,管道,共享内存,socket等等)
本文主要讲php利用linux 消息队列的通信方法
注意:多进程系列文章,都建立在linux环境,php-cli运行模式下
一:消息队列通信介绍
消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。 每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构。我们可以通过发送消息来避免命名管道的同步和阻塞问题。但是消息队列与命名管道一样,每个数据块都有一个最大长度的限制。
消息队列的最佳定义是:内核地址空间中的内部链表。消息可以顺序地发送到队列中,并以几种不同的方式从队列中获取。当然,每个消息队列都是由 IPC标识符所唯一标识的。
二:php消息队列扩展
php如果要使用linux的消息队列,需要安装
三:php使用消息队列
1:获取一个IPC标识符ftok();
ftok,可将项目路径与文件标识转换成一个IPC标识符,该标识符可用于创建消息队列
2:获取/创建一个消息队列msg_get_queue()
使用linux命令ipcs -q 可查看系统当前的消息队列数
3:插入数据到队列msg_send()
msg_send (
resource $queue(消息队列资源句柄) ,
int $msgtype(插入数据的类型,用来标识该队列自己的消息类型,自己自定义,必须大于0) ,
mixed $message(插入的数据,可以为数组,下一个参数可以序列化数据)
[, bool $serialize = TRUE(是否序列化数据,默认是)
[, bool $blocking = TRUE (如果消息太大而无法放入队列(linux消息队列限制),则脚本将等待另一个进程从队列中读取消息,并释放足够的空间以发送消息。这被称为阻塞; 您可以通过设置可选blocking参数来防止阻塞FALSE,在这种情况下,如果消息对于队列来说太大,msg_send()将立即返回,并将可选参数FALSE设置 errorcode为MSG_EAGAIN,表示您应稍后尝试再次发送消息。)
[, int &$errorcode ]]] (错误标识));
插入成功之后,ipcs可看到message多了一条:
4:取出一条数据msg_receive
msg_receive (
resource $queue , (消息队列资源句柄)
int $desiredmsgtype (要取出的消息队列类型,如果为0,则不筛选类型,直接返回最先插入的那条,大于0,则筛选类型,返回最先插入的类型数据,小于0,则返回小于等于绝对值的数据,如果消息队列暂无满足要求的数据,则阻塞或者返回false,由flag参数配置),
int &$msgtype (当取出数据时,该变量会赋值为该数据的类型),
int $maxsize (消息的最大大小被指定的被接受 maxsize; 如果队列中的消息大于此大小,则该功能将失败(除非flags按照以下说明设置 )该参数较迷,没有理解),
mixed &$message (当取出数据时,该变量会赋值为该数据)
[, bool $unserialize = TRUE(是否反序列化数据)
[, int $flags = 0
该选项flags允许您将标志传递给低级msgrcv系统调用。它默认为0,但您可以指定一个或多个以下值(通过将它们相加或相加)。msg_receive的标志值MSG_IPC_NOWAIT如果没有消息desiredmsgtype,立即返回,不要等待。该函数将失败并返回对应的整数值MSG_ENOMSG。
MSG_EXCEPT将此标志与desiredmsgtype大于0 结合使用 会导致函数接收到不等于的第一条消息desiredmsgtype。
MSG_NOERROR如果消息长于maxsize,则设置此标志将截断消息,maxsize并且不会发出错误信号。
[, int &$errorcode ]]] )如果该函数失败,errorcode则可选项将被设置为系统errno变量的值。
5:删除队列msg_remove_queue ( resource $queue )
顾名思义,该函数可删除一个消息队列
四:linux相关操作
在linux中,主要用ipcs(查看) ipcrm(删除)
1:ipcs
ipcs -h,可查看帮助
主要需要记住的是:
ipcs -q (查看消息队列)
ipcs -l (查看系统配置)
2:ipcrm
ipcrm -h:
ipcrm,只要能删除就行啦~~
ipcrm -q id (删除指定消息队列)
3:注意!
在使用消息队列时,请注意消息队列的默认限制(限制消息队列数,和消息队列大小),
当到达上限时,会使得写入消息队列操作阻塞(默认阻塞)
五:封装类
创建队列方法,好像有点问题(创建后无法正确使用队列,估计是__FILE__常量问题),暂时没查
使用封装类方法:$message_queue_key= ftok(__FILE__, 'a');
if(msg_queue_exists($message_queue_key)){//如果有该消息队列,则删除,用于清空之前队列的无用数据
msg_remove_queue(msg_get_queue($message_queue_key, 0666));
}
$message_queue= msg_get_queue($message_queue_key, 0666);
$msg_queue = new MsgQueue($message_queue);
/**
* Created by PhpStorm.
* User: tioncico
* Date: 18-5-29
* Time: 下午11:00
*/
class MsgQueue
{
public $queue;
public function __construct($queue)
{
$this->queue = $queue;
}
public function push($data, $type = 1)
{
$result = msg_send($this->queue, $type, $data);
return $result;
}
public function pop($type = 0,$flags = MSG_IPC_NOWAIT)
{
msg_receive($this->queue, $type, $message_type, 1024, $message,true,$flags);
// var_dump($message_type);
// msg_receive($this->queue,$type,$message_type,1024,$message);
return $message;
}
public function close()
{
return msg_remove_queue($this->queue);
}
/**
* 创建一个队列(TODO:疑问待解决)
* @param string $path_name
* @param string $prop
* @param string $perms
* @return array
*/
public static function getQueue($path_name = __FILE__, $prop = '1', $perms = '0666')
{
$data = array();
$data['queue_key'] = ftok($path_name, $prop);
$data['queue'] = msg_get_queue($data['queue_key'], $perms);
return $data;
}
}
七:使用例子<?php
include_once 'new/MsgQueue.php';
$message_queue_key= ftok(__FILE__, 'a');
$message_queue= msg_get_queue($message_queue_key, 0666);
$queue_obj = new MsgQueue($message_queue);
$pid = pcntl_fork();
if($pid>0){//主进程入列
while(1){
$msg = $queue_obj->push((array('a'=>321312,'v'=>'casd')),12456);
sleep(2);
}
}else{//子进程出列
while(1){
$message = $queue_obj->pop();
var_dump($message);
sleep(1);
}
}
输出:
本文为仙士可原创文章,转载无需和我联系,但请注明来自仙士可博客www.php20.cn
push msg php_php进程通信-消息队列相关推荐
- linux 进程通信 消息队列
详解linux进程间通信-消息队列 前言:前面讨论了信号.管道的进程间通信方式,接下来将讨论消息队列. 一.系统V IPC 三种系统V IPC:消息队列.信号量以及共享内存(共享存储器)之间有很多相似 ...
- ZUCC_操作系统原理实验_Lab9进程的通信消息队列
lab9进程的通信–消息队列 一.两个进程并发执行,通过消息队列,分别进行消息的发送和接收 1.代码: //接受消息 #include<stdio.h> #include<stdli ...
- Google guava 事件总线 EventBus 进程内消息队列
Google guava 事件总线 EventBus 创建事件总线流程 码代码 引入依赖 一个简单的事件处理 监听者 创建事件生产者总线.注册事件监听者.发送事件 运行结果 扩展 多个事件监听者加De ...
- linux 环境下的进程间的通信——消息队列传输结构体
linux 环境下的进程间的通信方式主要有:管道,有名和无名管道, 这种方式适用于具有亲缘关系的进程之间的通信: 信号: 消息队列: 共享内存: 信号量: 套接字: 这次主要涉及消息队列: 1. 需要 ...
- Linux进程之间通信 消息队列
使用命令 ipcs -q 查看对应的消息队列 代码 文件接收者 #include <sys/types.h> #include <stdio.h> #include < ...
- 基于C语言的线程通信消息队列实现
在多线程编程中经常需要进行线程与线程间的通信,由于线程间能够共享数据结构,也就是一个全局变量能够被两个线程同时候使用.但是要注意的是线程的同步和互斥. 线程同步是指线程之间所具有的一 ...
- php 多进程 消息队列,[PHP] 多进程通信-消息队列使用
向消息队列发送数据和获取数据的测试 $key=ftok(__file__,'a'); //获取消息队列 $queue=msg_get_queue($key,0666); //发送消息 //msg_se ...
- 使用multiprocesss模块进程通信采用队列方式,子进程run执行完一直不能退出的问题
进程间通信常用的方法有信号量.共享内存.消息队列,python的multiprocesss模块提供了与平台无关的进程相关的API 在项目中使用 multiprocesss 多进程编程时遇到奇怪的问题是 ...
- Linux进程通信之消息队列
目录 1.消息队列的原理: 2.消息队列的接口: (1)创建消息队列 (2)向消息队列发送消息 (3)接收消息 (4)操作消息队列的接口 1.消息队列的原理: 消息队列(messagequeue)以链 ...
- linux.调整收发队列,linux消息队列通信
程序目的:学习linux消息队列通信 所用主要函数:msgget(),msgsnd(),msgrcv(),msgctl() 首先介绍每个函数的用法: (1)msgget 使用格式: #include ...
最新文章
- ArrayAdapter requires the resource ID to be a TextView
- Appium+python自动化(八)- 初识琵琶女Appium(千呼万唤始出来,犹抱琵琶半遮面)- 下(超详解)...
- .NET Core 2.1改进了性能,并提供了新的部署选项
- C#中读取xml文件指定节点
- Ubuntu 18.04 如何添加或删除 SWAP 交换分区
- 三流面试聊JDK,二流面试聊JVM,一流面试……
- 连接数据库时提示归档器失败 ORA-00257: archiver error
- 前台用js、jquery出现错误很多是由于IE缓存
- 免费 Flash 留言板 -Powered by Kong
- idea maven dependencies 总是报红
- 我把自己的下半生用来写程序
- python如何监听toast提示信息_python 怎样获取toast?
- DevOps 和敏捷开发的区别是什么?
- svm公式推导及理解
- 【Re-ID】现有方法调研 - 无监督/半监督方法 - 其他方法
- 孟岩老师:Linux之父话糙理不糙
- python全栈是什么?
- 自动曝光修复算法附完整C代码
- Java练习题:字节缓冲流性能分析、 文档顺序恢复
- Jetson TX2 远程控制(Remote Control)