php multi-process - communication using message queues sysvmsg

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/raoxiaoya/article/details/100182273

The same can sysvmsg in PHP extensions to implement multi-process message queue

php -m |grep sysvmsg

This extension installed by default.

Because we know that, although in the context of the child is isolated, but the main process in the open fd and child processes are shared, it can be operated simultaneously.

The child is to spend preemptive queue, the consumer will not be repeated.

ftok()
	可以将一个路径转换成消息队列可用的key值
	
msg_get_queue()
	第一个参数 是消息队列的key,第二个参数是消息队列的读写权限,这个权限跟文件类似
	
msg_send()
	第1个参数 : resource $queue 表示要写入的消息队列资源。
	第2个参数 : int $msgtype 表示写入消息队列的 消息类型,这个参数是 配合 msg_receive读取消息队列函数 使用的,下面会说
	第3个参数 : mixed $message 你要发送的信息,最大为 65536 个字节。
	第4个参数 : bool $serialize = true 为可选项,是否序列化你发送的消息。
	第5个参数 : bool $blocking = true 是否阻塞,当你发送的消息很大,而此时的消息队列无法存入的时候,此时消息队列就会阻
	塞,除非等到有别的进程从消息队列中读取了别的消息,然后消息队列有足够的空间存储你要发送的信息,才能继续执行。你可以设
	置这个参数为false,这样你发送信息就会失败,此时错误信息会在 第6个参数 $errorcode中体现,错误码为 MSG_EAGAIN ,你
	可以根据这个错误码,重新发送你的消息。
	第6个参数 : int &$errorcode 记录写入中出现的一系列错误。
	
msg_receive()
	第1个参数:resource $queue 表示要读取的消息队列资源。
	第2个参数 :int $desiredmsgtype 读取的消息类型。这个参数为 0 的时候,你可以读取 msg_send 以任意 消息类型 发送的消
	息。 如果此参数和你发送的某个消息类型相同,比如你有 2个消息,一个是通过 1类型发送的,一个是通过2 类型发送的。你
	用 0 可以接收这两种消息 ,而你用 1 只能接收到 以1类型发送的消息。
	第3个参数 : int &$msgtype 你读取到的信息,它发送时的消息类型会存储在该参数中。
	第4个参数 : int $maxsize 你以多大的字节去读取消息,如果这个值小于你要读取的内容的长度,你会读取失败。
	第5个参数 :mixed &$message 读取的内容。
	第6个参数 : bool $unserialize = true 内容是否序列化
	第7个参数 :int $flags = 0 读取标识。除了默认的0 之外,还有3个参数可选 MSG_IPC_NOWAIT 这个参数表示如果没有从消息队
	列中读取到信息,会立马返回,并返回错误码 MSG_ENOMSG.
    MSG_EXCEPT 这个参数 是配合 第2个参数使用的,如果使用这个参数,你读取到的第一个参数,不是你第一个发送的参数。(队
    列先进先 出)
    MSG_NOERROR 如果读取的内容过大,而你指定的第4个参数又不够的时候,它会截断这个消息,并且不报错。
	
msg_remove_queue()
	销毁消息队列的方法

Example:

<?php
$key = ftok(__DIR__, 'm');

$resource = msg_get_queue($key);

// 主进程发送消息
for($i=0;$i<10;$i++){
    $bool = msg_send($resource, 1, 'input data '.$i, true, true, $errcode);
}

if(!$bool){
    die('errcode: '.$errcode);
}
// 子进程消费消息
$process = new Swoole\Process(function() use($resource){
    // 子进程内部
    // msg_receive会阻塞在这里消费
    while(true){
        $bool = msg_receive($resource, 0, $msg_type, 1024, $msg, true, 0);
        var_dump($msg_type);
        var_dump($msg);
        echo getmygid() . ': 正在消费: '.$msg.PHP_EOL;
    }
});

$process->start();

// 回收子进程
while($ret = Swoole\Process::wait(true)){

}

Optimized

Guess you like

Origin blog.csdn.net/raoxiaoya/article/details/100182273