1. 程式人生 > >PHP 程序間通訊——訊息佇列(msg_queue)

PHP 程序間通訊——訊息佇列(msg_queue)

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 是執行的檔名 
效果如下:

[[email protected]
~]# 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)

PHP 程序間通訊——訊息佇列 本文不涉及PHP基礎庫安裝。詳細安裝說明,請參考官網,或期待後續部落格分享。 1、訊息佇列函式準備 <?php //生成一個訊息佇列的key $msg_key = ftok(__FILE__, 'a'); //產生一個訊息佇列

php程序通訊--訊息佇列

首先我們來看一下如何建立一個訊息佇列。 //建立訊息佇列 $msg_key = ftok( __FILE__, 'a' ); $msg_queue = msg_get_queue( $msg_key, 0666 );  在php中通過這兩句話就可以建立一個訊息佇列。 ftok 函式,是可以

Linux關於程序通訊訊息佇列

訊息佇列概念 訊息佇列提供了一個從一個程序向另外一個程序傳送一塊資料的方法 每個資料塊都被認為是有一個型別,接收者程序接收的資料塊可以有不同的型別值 訊息佇列也有管道一樣的不足,就是每個資料塊的最大長度是有上限的,系統上全體佇列的最大總長度也有一個上限 訊息佇列函式操作

python 多程序通訊 訊息佇列

import multiprocessing import time #使用佇列,將訊息寫進佇列,需要的程序到佇列取 #佇列由父程序建立,子程序共享佇列 def write(qe): print("啟動子程序 write") for chr in ['A','B','C','D

程序通訊——訊息佇列

每個程序各自具有不同的使用者地址空間,任何一個程序的全域性變數在另外一個程序中看不到;所以程序之間要交換資料必須通過核心,在核心中開闢一塊緩衝區,程序1把資料從使用者空間拷到核心緩衝區,程序2再從核心緩

一步一步學linux之程序通訊——訊息佇列

一、什麼是訊息佇列:訊息佇列提供了一種程序與程序間傳送資料塊的一種方法,每個資料塊含有一個型別,接收程序可以獨立地接收含有不同型別的資料結構,可以通過傳送訊息來避免同步和阻塞問題。訊息佇列有最大長度限制       在分散式計算環境下,訊息佇列是為了對異構網路環境下的分散式應

Linux程序通訊——訊息佇列應用例項

    訊息佇列是訊息的連結表,包括Posix訊息佇列system V訊息佇列。有足夠許可權的程序可以向佇列中新增訊息,被賦予讀許可權的程序則可以讀走佇列中的訊息。訊息佇列克服了訊號承載資訊量少,管道只能承載無格式位元組流以及緩衝區大小受限等缺點。下面是兩個測試模組接收模組m

System V程序通訊---訊息佇列

一、訊息佇列模型 訊息佇列是訊息的鏈式佇列,下圖即為訊息佇列模型… 1、訊息佇列的基本屬性 struct msqid_ds { struct msqid_ds { struct ipc_perm msg_perm;

linux程序通訊--訊息佇列相關函式(ftok)詳解

ipc_perm中mode的含義 操作者 讀 寫 可讀可寫 使用者 0400 0200 0600 組 0040 0020 0060 其他 0004 0002 0006 5.  IPC物件的建立許可權     msgget、semget、sh

Linux 程序通訊——訊息佇列實現雙向通訊

函式: key_t ftok(const char *filename, int proj_id); 通過檔名和專案號獲得System V IPC鍵值(用於建立訊息佇列、共享記憶體所用) proj_id:專案號,不為0即可 返回:成功則返回鍵值,失敗則返回-1 函式: in

php程序通訊--共享記憶體

php如何實現共享記憶體。(注意:本示例是在linux下,請勿在windows下嘗試此程式碼,並且必須是在php-cli模式下) php提供了兩種實現共享記憶體的擴充套件。下面我們來一一講解。   一、shmop 系類函式 <?php $shm_key = ftok(__FILE

php程序通訊--有名管道

管道PIPE   管道用於承載簡稱之間的通訊資料。為了方便理解,可以將管道比作檔案,程序A將資料寫到管道P中,然後程序B從管道P中讀取資料。php提供的管道操作API與操作檔案的API基本一樣,除了建立管道使用posix_mkfifo函式,讀寫等操作均與檔案操作函式相同。當然,你可以直接使用檔案

php程序通訊--訊號

php程序間通訊的另外一個手段就是通過 訊號 來在程序間傳遞資訊。訊號是一種系統呼叫。通常我們用的kill命令就是傳送某個訊號給某個程序的。具體有哪些訊號可以在liunx/mac中執行kill -l檢視。 一些php訊號的意思如下: SIGHUP 終止程序

php程序通訊--訊號量

 訊號量是什麼? 訊號量 : 又稱為訊號燈、旗語 用來解決程序(執行緒同步的問題),類似於一把鎖,訪問前獲取鎖(獲取不到則等待),訪問後釋放鎖。   舉一個生活中的例子:以一個停車場的運作為例。簡單起見,假設停車場只有三個車位,一開始三個車位都是空的。這時如果同時來了五輛車,看門人允許

程序通訊佇列,管道,檔案,共享記憶體,訊號量,事件,互斥鎖,socket

2017/11/4 程序間通訊,程序池 程序間通訊(IPC,inter-process communication):生產程序生產食物,消費程序購買食物,消費程序一直監視生產狀況,只要一有食物就將其取出來,如果取到食物None,兩者關係結束,於是主程序也結束。 遠端過程呼叫

從併發處理談PHP程序通訊----併發鎖表操作

程序間通訊 程序間通訊(IPC,Inter-Process Communication),多程序開發中,程序間通訊是一個永遠也繞不開的問題。在 web開發中,我們經常遇到的併發請求問題,本質上也可以作為程序間通訊來處理。 程序間通訊,指至少兩個程序或執行緒間傳送資料或訊號的一些技術或方法。程序是計

程序通訊——訊息傳遞(訊號量同步PV操作)

【申明:本文僅限於自我歸納總結和相互交流,有紕漏還望各位指出。 聯絡郵箱:[email protected]】 在多工作業系統環境下,多程序/多執行緒間同時執行,並且這些程序之間存在一定的關聯,多個程序/執行緒可能為了完成同一個任務相互協作,這就是程序之間的同步,

Linux:程序通訊(匿名管道命名管道)(共享記憶體,訊息佇列,訊號量)

目錄 程序間通訊的介紹 管道 匿名管道 原理: 程式碼實現 匿名管道特性 實現管道符 |  命名管道 命名管道特性 程式碼實現 管道讀寫規則 作業系統中ipc的相關命令 共享記憶體(重點) 生命週期: 程式碼實現 程式碼實現獲

Linux中程序通訊機制----訊息佇列

一、什麼是訊息 訊息(message)是一個格式化的可變長的資訊單元。訊息機制允許由一個程序給其它任意的程序傳送一個訊息。當一個程序收到多個訊息時,可將它們排成一個訊息佇列。 1、訊息機制的資料結構 (1)訊息首部 記錄一些與訊息有關的資訊,如訊息的型別、大小、

程序通訊的方式——訊號、管道、訊息佇列、共享記憶體

多程序: 首先,先來講一下fork之後,發生了什麼事情。 由fork建立的新程序被稱為子程序(child process)。該函式被呼叫一次,但返回兩次。兩次返回的區別是子程序的返回值是0,而父程序的返回值則是新程序(子程序)的程序 id。將子程序id返回給父程序的理由是