php多進程

來源:互聯網
上載者:User

標籤:store   隊列   wait   類型   過程   roc   echo   準備   lis   

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多進程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.