PHP pcntl_fork 多进程下载网页图片
pcntl_fork — 在当前进程当前位置产生分支(子进程)。译注:fork是创建了一个子进程,父进程和子进程都从fork的位置开始向下继续执行,不同的是父进程执行过程中,得到的fork返回值为子进程号,而子进程得到的是0。
#!/usr/bin/php <?php // 需要抓取的网页地址 $url = 'http://www.fengdingbo.com/category/linux'; $content = file_get_contents($url); preg_match_all('/<img\s+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 */ |