PHP pcntl_fork — 在當前進程當前位置產生分支,子進程,譯注:fork是創建了一個子進程,父進程和子進程 都從fork的位置開始向下繼續執行,不同的是父進程執行過程中,得到的fork返回值為子進程號,而子進程得到的是0.
注意:PHP有個pcntl_fork的函數可以實現多進程,但要加載pcntl拓展,而且只有在linux下才能編譯這個拓展.
1.首先在ubuntu下編譯pcntl.so,我的ubuntu下找不到pcntl的包,于是創建一個文件夾下載了整個PHP包,在里面找到了pcntl包運行如下命令,代碼如下:
- # mkdir php
- # cd php
- # apt-get source php5
- # cd php5-(WHATEVER_RELEASE)/ext/pcntl
- # phpize
- # ./configure (注一)
- # make
- # make install phpize 命令是用來準備 PHP 外掛模塊的編譯環境的
成功的安裝將建立 extname.so 并放置于 PHP 的外掛模塊目錄中(預設存放于 /usr/lib/php/modules/ 內),需要調整 php.ini,加入 extension=extname.so 這一行之后才能使用此外掛模塊.
例:void pcntl_exec(string $path [,array $args [,array $envs ]])
pcntl_exec — 在當前進程空間執行指定程序,代碼如下:
- $cmds=array(
- array('/home/jerry/projects/www/test2.php'),
- array('/home/jerry/projects/www/test3.php')
- );
- foreach($cmds as $cmd){
- $pid=pcntl_fork();
- if($pid==-1){
- //進程創建失敗
- echo '創建子進程失敗時返回-1';
- exit(-1);
- }
- else if($pid){
- //父進程會得到子進程號,所以這里是父進程執行的邏輯
- pcntl_wait($status,WNOHANG);
- }
- else{
- //子進程處理邏輯
- sleep(5);
- pcntl_exec('/usr/bin/php',$cmd);
- exit(0);
- }
- }
例,實例多圖片同步下載,代碼如下:
- #!/usr/bin/php
- <?php
- // 需要抓取的網頁地址
- $url = 'http://www.49028c.com';
- $content = file_get_contents($url);
- preg_match_all('/<imgs+src="(.*?)"/', $content, $matches,PREG_SET_ORDER);
- echo "已發現".count($matches)."張圖片n";
- list($sm, $ss) = explode(" ", microtime());
- foreach ($matches as $k => $val)
- {
- $pid[$k] = pcntl_fork();
- if(!$pid[$k])
- {
- download($url, $val);
- // 子進程要exit否則會進行遞歸多進程,父進程不要exit否則終止多進程
- exit(0);
- }
- if ($pid[$k])
- {
- // pcntl_waitpid($pid[$k], $status, WUNTRACED);
- }
- }
- echo "下載完成n";
- list($em, $es) = explode(" ", microtime());
- echo "用時:",($es+$em) - ($ss + $sm),"n";
- /**
- * 抓取網頁圖片
- *
- */
- 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 */
- ?>
新聞熱點
疑難解答