成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

php進(jìn)程通信--System V 消息隊(duì)列

vboy1010 / 2929人閱讀

摘要:在中,進(jìn)程通信的方法有,消息隊(duì)列,共享內(nèi)存,信號(hào)量這些的相關(guān)方法默認(rèn)是不開啟的,如果需要,則要再編譯安裝的時(shí)候打開管道和消息隊(duì)列以及信號(hào)量是內(nèi)核級(jí)的共享信息的方式。然后就是多進(jìn)程間通信了。

在php中,進(jìn)程通信的方法有FIFO,System V消息隊(duì)列,SystemV共享內(nèi)存,System V信號(hào)量
這些System V的相關(guān)方法默認(rèn)是不開啟的,如果需要,則要再編譯安裝的時(shí)候打開
--enable-sysvsem --enable --sysvshm --enable-sysvmsg
管道和System V消息隊(duì)列以及System V信號(hào)量是內(nèi)核級(jí)的共享信息的方式。兩個(gè)或多個(gè)進(jìn)程共享駐留在內(nèi)核中的某些信息。訪問共享信息的每次操作涉及對(duì)內(nèi)核的一次系統(tǒng)調(diào)用。
消息隊(duì)列中的每個(gè)消息相關(guān)聯(lián)的類型字段提供了兩個(gè)特性

類型字段可以用于標(biāo)識(shí)消息,從而允許多個(gè)進(jìn)程在單個(gè)隊(duì)列上復(fù)用(multiplex)消息。 例如,類型字段的某個(gè)值用于標(biāo)識(shí)從各個(gè)客戶到服務(wù)器的消息,對(duì)于每一個(gè)客戶均為唯一的另外某個(gè)值用于標(biāo)識(shí)從服務(wù)器到各個(gè)客戶的消息。每個(gè)客戶的進(jìn)程ID自然可以用作對(duì)于每個(gè)客戶均為唯一的類型字段。

類型字段可以用作優(yōu)先級(jí)字段。這允許接受者以不同于先進(jìn)先出FIFO的某個(gè)順序讀出各個(gè)消息。這點(diǎn)不同于管道或FIFO,使用管道時(shí),數(shù)據(jù)必須是以寫入的順序讀出。使用System V消息隊(duì)列時(shí),消息能夠以任意順序讀出,之喲啊跟消息類型關(guān)聯(lián)的值一致就行。而且我們可以指定MSG_IPC_NOWAIT標(biāo)志調(diào)用msg_receive從某個(gè)隊(duì)列中讀出某個(gè)給定類型的任意消息,但是沒有給定類型的消息存在,那就立即返回。

本文主要記錄一下php利用消息隊(duì)列進(jìn)行通信的方法和心得。

// 生成一個(gè)消息隊(duì)列的key

// 生成一個(gè)消息隊(duì)列的key
$msgKey = ftok(__FILE__,"w");

/**
    msg_get_queue() returns an id that can be used to access the System V message
    queue with the given {key}. The first call creates the message queue with the
    optional {perms}. A second call to msg_get_queue() for the same {key} will
    return a different message queue identifier, but both identifiers access the
    same underlying message queue.
 */
// 產(chǎn)生一個(gè)消息隊(duì)列
$msgQueue = msg_get_queue($msgKey,0666);

// 檢查一個(gè)隊(duì)列是否存在
$status = msg_queue_exists($msgKey);
var_dump($status);

// 查看當(dāng)前消息的一些詳細(xì)信息
/**
 * msg_perm.uid The uid of the owner of the queue.
 * msg_perm.gid The gid of the owner of the queue.
 * msg_perm.mode The file access mode of the queue.
 * msg_stime The time that the last message was sent to the queue.
 * msg_rtime The time that the last message was received from the queue.
 * msg_ctime The time that the queue was last changed.
 * msg_qnum The number of messages waiting to be read from the queue.
 * msg_qbytes The maximum number of bytes allowed in one message queue. On Linux, this value may be read and modified via /proc/sys/kernel/msgmnb.
 * msg_lspid The pid of the process that sent the last message to the queue.
 * msg_lrpid The pid of the process that received the last message from the queue.
 *
 */
$msgStat = msg_stat_queue($msgQueue);
print_r($msgStat);

// 把數(shù)據(jù)加入消息隊(duì)列,默認(rèn)數(shù)據(jù)會(huì)被序列化
msg_send($msgQueue,1,"hahha,1");
msg_send($msgQueue,2,"ooooo,2");
msg_send($msgQueue,1,"xxxxx,3");

// 從消息隊(duì)列中讀取一條消息

msg_receive($msgQueue,1, $message_type, 1024, $message1);
msg_receive($msgQueue,1, $message_type, 1024, $message2);
//msg_receive($msgQueue,1, $message_type, 1024, $message3,true,MSG_IPC_NOWAIT);
msg_receive($msgQueue,2, $message_type, 1024, $message3);
$msgStat = msg_stat_queue($msgQueue);
print_r($msgStat);

msg_remove_queue($msgQueue);
echo $message1.PHP_EOL;
echo $message2.PHP_EOL;
echo $message3.PHP_EOL;

結(jié)果如下:

Array
(
    [msg_perm.uid] => 0
    [msg_perm.gid] => 0
    [msg_perm.mode] => 438
    [msg_stime] => 0
    [msg_rtime] => 0
    [msg_ctime] => 1492759388
    [msg_qnum] => 0
    [msg_qbytes] => 16384
    [msg_lspid] => 0
    [msg_lrpid] => 0
)
Array
(
    [msg_perm.uid] => 0
    [msg_perm.gid] => 0
    [msg_perm.mode] => 438
    [msg_stime] => 1492759388
    [msg_rtime] => 1492759388
    [msg_ctime] => 1492759388
    [msg_qnum] => 0
    [msg_qbytes] => 16384
    [msg_lspid] => 23336
    [msg_lrpid] => 23336
)
hahha,1
xxxxx,3
ooooo,2

手冊(cè)中對(duì)msg_send和msg_receive這兩個(gè)定義如下。

bool msg_send ( resource $queue , int $msgtype , mixed $message [, bool $serialize = true [, bool $blocking = true [, int &$errorcode ]]] )
msg_send() sends a message of type msgtype (which MUST be greater than 0) to the message queue specified by queue. 

bool msg_receive ( resource $queue , int $desiredmsgtype , int &$msgtype , int $maxsize , mixed &$message [, bool $unserialize = true [, int $flags = 0 [, int &$errorcode ]]] )
msg_receive() will receive the first message from the specified queue of the type specified by desiredmsgtype. 

msg_receive的第二個(gè)參數(shù)desiredmsgtype ,指定從隊(duì)列中獲取什么樣的消息。

如果desiredmsgtype等于0,那么就返回改隊(duì)列中的第一個(gè)消息。每一個(gè)消息隊(duì)列都是作為一個(gè)先進(jìn)先出的鏈表維護(hù),因此type為0,返回該隊(duì)列中最早的消息。(但是這個(gè)情況下,會(huì)出現(xiàn)阻塞,$flags要設(shè)置為MSG_IPC_NOWAIT)

如果desiredmsgtype 大于0,那就返回其類型值為desiredmsgtype的第一個(gè)消息。

如果desiredmsgtype 小于0,那就返回其類型值小于或等于desiredmsgtype參數(shù)的絕對(duì)值的消息中類型最小的第一個(gè)消息。(但是這個(gè)情況下,會(huì)出現(xiàn)阻塞,$flags要設(shè)置為MSG_IPC_NOWAIT)

如果你要讀取的那類消息不存在,程序就會(huì)阻塞,直到有對(duì)應(yīng)類型的消息寫入到隊(duì)列里。當(dāng)然,可以通過設(shè)置$flags = MSG_IPC_NOWAIT來設(shè)置為非阻塞。

然后就是多進(jìn)程間通信了。代碼如下:

// 獲取消息隊(duì)列key
$key = ftok(__FILE__,"w");

// 創(chuàng)建一個(gè)消息隊(duì)列
$queue = msg_get_queue($key);

$child = [];
$num   = 5;
$result = [];

for($i=0;$i<$num;$i++){
    $pid = pcntl_fork();
    if($pid == -1) {
        die("fork failed");
    } else if ($pid > 0) {
        $child[] = $pid;
    } else if ($pid == 0) {
        $sleep = rand(1,4);
        msg_send($queue,2,array("name" => $i."~".$sleep));
        sleep($sleep);
        exit(0);
    }
}

while(count($child)){
    foreach($child as $k => $pid) {
        $res = pcntl_waitpid($pid,$status,WNOHANG);
        if ($res == -1 || $res > 0 ) {
            unset($child[$k]);
            msg_receive($queue,2,$message_type,1024,$data);
            $result[] = $data;
        }
    }
}
msg_remove_queue($queue);
print_r($result);

結(jié)果如下:

Array
(
    [0] => Array
        (
            [name] => 1~3
        )

    [1] => Array
        (
            [name] => 0~3
        )

    [2] => Array
        (
            [name] => 3~2
        )

    [3] => Array
        (
            [name] => 4~4
        )

    [4] => Array
        (
            [name] => 2~4
        )

)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/22826.html

相關(guān)文章

  • PHP進(jìn)程通信

    摘要:一進(jìn)程間通信理解間進(jìn)程通信機(jī)制,先了解下進(jìn)程間有哪些通訊機(jī)制歷史發(fā)展按照歷史來源主要有兩大塊的管道,,信號(hào)的消息隊(duì)列,共享內(nèi)存,信號(hào)燈。信號(hào)量主要作為進(jìn)程間,以及進(jìn)程內(nèi)部線程之間的通訊手段。主要依賴,兼容擴(kuò)展實(shí)現(xiàn)方式的進(jìn)程間通信之消息隊(duì)列。 PHP間進(jìn)程如何通信,PHP相關(guān)的服務(wù)的IPC是實(shí)現(xiàn)方式,IPC的思想如何用到項(xiàng)目中。 一、linux進(jìn)程間通信 理解php間進(jìn)程通信機(jī)制,先了解...

    haobowd 評(píng)論0 收藏0
  • 進(jìn)程通信

    摘要:接受不到消息消息隊(duì)列通過指定而被創(chuàng)建后,任意一方銷毀了該隊(duì)列,都會(huì)導(dǎo)致其他發(fā)送或接收方失敗。用法場(chǎng)景進(jìn)程,中代碼段要用到中代碼段的結(jié)果。完成了進(jìn)程間同步問題此外進(jìn)程間通信采用的方式是共享內(nèi)存。 參考文章 深刻理解Linux進(jìn)程間通信(IPC) 進(jìn)程間通信(IPC)介紹 php高級(jí)應(yīng)用之進(jìn)程控制及進(jìn)程間通訊 workman 作者發(fā)布 PHP 相關(guān)進(jìn)程間通信擴(kuò)展 -- System V ...

    Richard_Gao 評(píng)論0 收藏0
  • PHP進(jìn)程進(jìn)程通信

    摘要:擴(kuò)展完成兼容機(jī)通用如獲取進(jìn)程殺死進(jìn)程等。擴(kuò)展實(shí)現(xiàn)方式的進(jìn)程間通信之消息隊(duì)列。四進(jìn)程間通信通常中的進(jìn)程通信方式有消息隊(duì)列信號(hào)量共享內(nèi)存信號(hào)管道。下面這個(gè)例子中,父進(jìn)程等待秒鐘,向子進(jìn)程發(fā)送信號(hào)。子進(jìn)程捕獲信號(hào),掉信號(hào)處理函數(shù)處理。 一、引言 進(jìn)程是一個(gè)具有獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合的一次運(yùn)行活動(dòng)。換句話說就是,在系統(tǒng)調(diào)度多個(gè)cpu的時(shí)候,一個(gè)程序的基本單元。進(jìn)程對(duì)于大多數(shù)的語言都不是...

    高勝山 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<