中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP之pcntl_fork多進程并發編程示例

發布時間:2020-04-02 12:12:05 來源:網絡 閱讀:1658 作者:cj31415 欄目:web開發

    待下載的網頁地址放在$urls數組中,按指定的并發數多進程下載網頁,下載的網頁保存在本地硬盤,下載的網頁大小通過linux消息隊列發送給父進程累加,全部網頁下載完成后,父進程顯示下載的網頁數、字節數。代碼如下。

<?
//$urls數組用于保存要下載的網址,實際應用中一般從文件或數據庫中讀取網址保存到$urls中。
$urls = array('http://www.qq.com','http://www.sohu.com','http://www.sina.com.cn',....);
$urls_num = count($urls);//數組大小,也是網址數量
$msg_file = "/tmp/download_msgqueue.txt";//下面3行創建linux消息隊列下,該文件須先創建好
$msg_queuekey = ftok($msg_file,'R');//touch /tmp/download_msgqueue.txt
$msg_queue = msg_get_queue($msg_queuekey, 0666); 
$maxtasknum = 5;//設定并發進程數
$ct = 0;//$urls數組用的計數器
$cttask = 0;//并發進程計數器
$pids = array();//保存進程的數組
$total_bytes = 0;//下載網頁的字節數
while ($ct<$urls_num) {//循環抓取$urls數組中指定的網頁
while ($cttask<$maxtasknum && $ctproc<$urls_num) {//fork出指定的并發數進程
$pids[$ct] = pcntl_fork();
if ($pids[$ct]==-1) {
echo "create subproc fail.\n";
exit(0);
}
elseif ($pids[$ct]>0) {//父進程
}
elseif ($pids[$ct]==0) {//子進程
download($urls[$ct], $msg_queue);
exit(0);
}
$cttask++;
$ct++;
}
$tmppid = pcntl_waitpid(0, $status);//等待子進程結束
foreach($pids as $key => $pid) {
    if($tmppid == $pid){
    unset($pids[$key]);
    $cttask--;//子進程結束后,并發進程計數器減1
    }
}
do {//從消息隊列出取出每個網頁的大小,計算下載的字節數。如果要下載的網頁很多,需要把此段代碼放到下載網頁的循環中,否則可能會出現隊列滿的情況。
msg_receive($msg_queue, 0, $message_type, 16, $message, true, MSG_IPC_NOWAIT); 
//echo "[".$message."]\n";
$total_bytes += $message;
$a = msg_stat_queue($msg_queue);
if($a['msg_qnum'] == 0){//這種方式退出比$ct==$urls_num好,因為如果fork==-1,就不會有$urls_num個消息,程序會永遠等待消息。
    break;
}
} while(true);
}
while ($cttask > 0) {//等待最后$cttask個子進程結束
$tmppid = pcntl_waitpid(0,$status);
foreach($pids as $key => $pid) {
    if($tmppid == $pid){
    unset($pids[$key]);
    $cttask--;
    }
}
}
do {//取得最后$cttask個子進程的消息
msg_receive($msg_queue, 0, $message_type, 16, $message, true, MSG_IPC_NOWAIT); 
//echo "[".$message."]\n";
$total_bytes += $message;
$a = msg_stat_queue($msg_queue);
if($a['msg_qnum'] == 0){
    break;
}
} while(true);
msg_remove_queue($msg_queue);//刪除消息隊列
echo "\nDone. download: ".$urls_num." pages,total: ".round($total_bytes/1024,3)." KB \n";
exit(0);
function download($url, $msg_queue) {//下載指定網頁,把內容保存在本地硬盤,并下載內容的長度放入消息隊列中
$dirname = "/tmp/donwload/";//保存下載網頁的目錄,要事先創建好
$content = file_get_contents($url);
if ($content === false) {
$content = 0;
}
$url_parts = parse_url($url);
$fname = $dirname.$url_parts['host'];
$ret = file_put_contents($fname, $content);
msg_send($msg_queue, 1, strlen($content));
} 
?>

參考資料:

PHP實現進程間通信:消息隊列 https://www.douban.com/note/245520545/


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

济阳县| 缙云县| 团风县| 金山区| 蓬莱市| 石城县| 宁乡县| 涡阳县| 鄂托克前旗| 垣曲县| 固原市| 金堂县| 六枝特区| 孝感市| 乌兰浩特市| 竹溪县| 尤溪县| 凌海市| 元阳县| 鹤岗市| 昭觉县| 博乐市| 天长市| 龙陵县| 台中市| 西乌| 新巴尔虎左旗| 延安市| 晋江市| 萨迦县| 达日县| 甘泉县| 郁南县| 云浮市| 吉安市| 逊克县| 宿迁市| 河津市| 普兰县| 瑞金市| 清苑县|