PHP使用pcntl_fork實(shí)現(xiàn)多進(jìn)程下載圖片的方法
本文實(shí)例講述了PHP使用pcntl_fork實(shí)現(xiàn)多進(jìn)程下載圖片的方法。分享給大家供大家參考。具體分析如下:
PHP pcntl_fork — 在當(dāng)前進(jìn)程當(dāng)前位置產(chǎn)生分支,子進(jìn)程,譯注:fork是創(chuàng)建了一個(gè)子進(jìn)程,父進(jìn)程和子進(jìn)程 都從fork的位置開(kāi)始向下繼續(xù)執(zhí)行,不同的是父進(jìn)程執(zhí)行過(guò)程中,得到的fork返回值為子進(jìn)程號(hào),而子進(jìn)程得到的是0.
注意:PHP有個(gè)pcntl_fork的函數(shù)可以實(shí)現(xiàn)多進(jìn)程,但要加載pcntl拓展,而且只有在linux下才能編譯這個(gè)拓展.
1.首先在ubuntu下編譯pcntl.so,我的ubuntu下找不到pcntl的包,于是創(chuàng)建一個(gè)文件夾下載了整個(gè)PHP包,在里面找到了pcntl包運(yùn)行如下命令,代碼如下:
# cd php
# apt-get source php5
# cd php5-(WHATEVER_RELEASE)/ext/pcntl
# phpize
# ./configure (注一)
# make
# make install phpize 命令是用來(lái)準(zhǔn)備 PHP 外掛模塊的編譯環(huán)境的
成功的安裝將建立 extname.so 并放置于 PHP 的外掛模塊目錄中(預(yù)設(shè)存放于 /usr/lib/php/modules/ 內(nèi)),需要調(diào)整 php.ini,加入 extension=extname.so 這一行之后才能使用此外掛模塊.
例:
pcntl_exec — 在當(dāng)前進(jìn)程空間執(zhí)行指定程序,代碼如下:
array('/home/jerry/projects/www/test2.php'),
array('/home/jerry/projects/www/test3.php')
);
foreach($cmds as $cmd){
$pid=pcntl_fork();
if($pid==-1){
//進(jìn)程創(chuàng)建失敗
echo '創(chuàng)建子進(jìn)程失敗時(shí)返回-1';
exit(-1);
}
else if($pid){
//父進(jìn)程會(huì)得到子進(jìn)程號(hào),所以這里是父進(jìn)程執(zhí)行的邏輯
pcntl_wait($status,WNOHANG);
}
else{
//子進(jìn)程處理邏輯
sleep(5);
pcntl_exec('/usr/bin/php',$cmd);
exit(0);
}
}
例,實(shí)例多圖片同步下載,代碼如下:
<?php
// 需要抓取的網(wǎng)頁(yè)地址
$url = 'http://www.dbjr.com.cn';
$content = file_get_contents($url);
preg_match_all('/<imgs+src="(.*?)"/', $content, $matches,PREG_SET_ORDER);
echo "已發(fā)現(xiàn)".count($matches)."張圖片n";
list($sm, $ss) = explode(" ", microtime());
foreach ($matches as $k => $val)
{
$pid[$k] = pcntl_fork();
if(!$pid[$k])
{
download($url, $val);
// 子進(jìn)程要exit否則會(huì)進(jìn)行遞歸多進(jìn)程,父進(jìn)程不要exit否則終止多進(jìn)程
exit(0);
}
if ($pid[$k])
{
// pcntl_waitpid($pid[$k], $status, WUNTRACED);
}
}
echo "下載完成n";
list($em, $es) = explode(" ", microtime());
echo "用時(shí):",($es+$em) - ($ss + $sm),"n";
/**
* 抓取網(wǎng)頁(yè)圖片
*
*/
function download($url, $val)
{
$pic_url = $val[1];
if (strpos($val[1], '//') !== false)
{
;
}
elseif (preg_match('@^(.*?)/@', $val[1], $inner_matches) == 0)
{
$pic_url = $url.$val[1];
}
elseif (preg_match('@[:.]@', $inner_matches[1], $tmp_matches) == 0)
{
$pic_url = $url.$val[1];
}
$pic = file_get_contents($pic_url);
if ($pic === false)
{
return;
}
preg_match('@/([^/]+)$@', $pic_url, $tmp_matches);
// 可使用assert處理異常
$pic_file_name = $tmp_matches[1];
$f = fopen("tmp/".$pic_file_name, "wb"); #
fwrite($f, $pic);
fclose($f);
}
/* End of file pcntl_fork.php */
?>
希望本文所述對(duì)大家的PHP程序設(shè)計(jì)有所幫助。
相關(guān)文章
實(shí)用PHP會(huì)員權(quán)限控制實(shí)現(xiàn)原理分析
本文是對(duì)PHP權(quán)限的教程。非常實(shí)用。學(xué)習(xí)php的朋友可以參考下。2011-05-05php生成動(dòng)態(tài)驗(yàn)證碼gif圖片
這篇文章主要介紹了php生成動(dòng)態(tài)驗(yàn)證碼gif圖片的相關(guān)資料,需要的朋友可以參考下2015-10-10PHP項(xiàng)目在Docker(WSL2)中運(yùn)行緩慢的解決方法
最近在使用Docker容器運(yùn)行PHP項(xiàng)目的時(shí)候,發(fā)現(xiàn)特別緩慢,例如一個(gè)干凈的?ThinkPHP?5.1?框架,訪(fǎng)問(wèn)首頁(yè)都需要1秒以上,如果再加上數(shù)據(jù)庫(kù)查詢(xún)、復(fù)雜的業(yè)務(wù)邏輯等代碼的話(huà),那速度可想而知,所以本文就給大家介紹了解決方法,需要的朋友可以參考下2023-09-09php實(shí)現(xiàn)的支持imagemagick及gd庫(kù)兩種處理的縮略圖生成類(lèi)
這篇文章主要介紹了php實(shí)現(xiàn)的支持imagemagick及gd庫(kù)兩種處理的縮略圖生成類(lèi),包含了用法的詳細(xì)描述,非常實(shí)用,需要的朋友可以參考下2014-09-09PHP函數(shù)之error_reporting(E_ALL ^ E_NOTICE)詳細(xì)說(shuō)明
在看帝國(guó)cms的connect.php是發(fā)現(xiàn)第一句是error_reporting(E_ALL ^ E_NOTICE);以前也沒(méi)注意過(guò)這個(gè)語(yǔ)句,知道是設(shè)置錯(cuò)誤提示的,但不清楚具體怎樣設(shè)置使用。下面從網(wǎng)上摘抄了些東西,總結(jié)了一下。2011-07-07PHP創(chuàng)建對(duì)象的六種方式實(shí)例總結(jié)
這篇文章主要介紹了PHP創(chuàng)建對(duì)象的六種方式,結(jié)合實(shí)例形式總結(jié)分析了php類(lèi)的定義及對(duì)象實(shí)例化常見(jiàn)操作技巧,需要的朋友可以參考下2019-06-06