PHP多进程(4) :内部多进程
说的都是只兼容unix 服务器的多进程,下面来讲讲在window 和 unix 都兼容的多进程(这里是泛指,下面的curl实际上是通过IO复用实现的)。
通过扩展实现多线程的典型例子是CURL,CURL 支持多线程的抓取网页的功能。
这部分过于抽象,所以,我先给出一个CURL并行抓取多个网页内容的一个分装类。这个类实际上很实用,
详细分析这些函数的内部实现将在下一个教程里面描述。
你可能不能很好的理解这个类,而且,php curl 官方主页上都有很多错误的例子,在讲述了其内部机制
后,你就能够明白了。
先看代码:
class Http_MultiRequest
{
//要并行抓取的url 列表
private $urls = array(); //curl 的选项
private $options; //构造函数
function __construct($options = array())
{
$this->setOptions($options);
} //设置url 列表
function setUrls($urls)
{
$this->urls = $urls;
return $this;
} //设置选项
function setOptions($options)
{
$options[CURLOPT_RETURNTRANSFER] = ;
if (isset($options['HTTP_POST']))
{
curl_setopt($ch, CURLOPT_POST, );
curl_setopt($ch, CURLOPT_POSTFIELDS, $options['HTTP_POST']);
unset($options['HTTP_POST']);
} if (!isset($options[CURLOPT_USERAGENT]))
{
$options[CURLOPT_USERAGENT] = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;)';
} if (!isset($options[CURLOPT_FOLLOWLOCATION]))
{
$options[CURLOPT_FOLLOWLOCATION] = ;
} if (!isset($options[CURLOPT_HEADER]))
{
$options[CURLOPT_HEADER] = ;
}
$this->options = $options;
} //并行抓取所有的内容
function exec()
{
if(empty($this->urls) || !is_array($this->urls))
{
return false;
}
$curl = $data = array();
$mh = curl_multi_init();
foreach($this->urls as $k => $v)
{
$curl[$k] = $this->addHandle($mh, $v);
}
$this->execMulitHandle($mh);
foreach($this->urls as $k => $v)
{
$data[$k] = curl_multi_getcontent($curl[$k]);
curl_multi_remove_handle($mh, $curl[$k]);
}
curl_multi_close($mh);
return $data;
} //只抓取一个网页的内容。
function execOne($url)
{
if (empty($url)) {
return false;
}
$ch = curl_init($url);
$this->setOneOption($ch);
$content = curl_exec($ch);
curl_close($ch);
return $content;
} //内部函数,设置某个handle 的选项
private function setOneOption($ch)
{
curl_setopt_array($ch, $this->options);
} //添加一个新的并行抓取 handle
private function addHandle($mh, $url)
{
$ch = curl_init($url);
$this->setOneOption($ch);
curl_multi_add_handle($mh, $ch);
return $ch;
} //并行执行(这样的写法是一个常见的错误,我这里还是采用这样的写法,这个写法
//下载一个小文件都可能导致cup占用100%, 并且,这个循环会运行10万次以上
//这是一个典型的不懂原理产生的错误。这个错误在PHP官方的文档上都相当的常见。)
private function execMulitHandle2($mh)
{
$i = ;
$running = null;
do {
curl_multi_exec($mh, $running);
$i++;
} while ($running > );
//var_dump($i);
} //应该用这样的写法
private function execMulitHandle($mh)
{
$i = ;
do {$mrc = curl_multi_exec($mh,$active); $i++;} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active && $mrc == CURLM_OK)
{
if (curl_multi_select($mh) != -)
{
do {$mrc = curl_multi_exec($mh, $active); $i++;} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
$i++;
}
//var_dump($i);
}
}
看最后一个注释最多的函数,这个错误在平时调试的时候可能不太容易发现,因为程序完全正常,但是,在生产服务器下,马上会引起崩溃效果。
解释为什么不能这样,必须从C 语言内部实现的角度来分析。这个部分将放到下一个教程(PHP高级编程之–单线程实现并行抓取网页 )。不过不是通过C语言来表述原理,而是通过PHP
这个类,实际上也就很简单的实现了前面我们费了4个教程的篇幅,并且是九牛二虎之力才实现的多线程的抓取网页的功能。在纯PHP的实现下,我们只能用一个后台服务的方式来比较好的实现,但是当你使用 操作系统接口语言 C 语言时候,这个实现当然就更加的简单,灵活,高效。
就同时抓取几个网页这样一件简单的事情,实际上在底层涉及到了很多东西,对很多半路出家的PHP程序员,可能不喜欢谈多线程这个东西,深入了就涉及到操作系统,浅点说就是并行运行好几个“程序”。但是,很多时候,多线程必不可少,比如要写个快点的爬虫,往往就会浪费九牛二虎之力。不过,PHP的程序员现在应该感谢CURL 这个扩展,这样,你完全不需要用你不太精通的 python 去写爬虫了,对于一个中型大小的爬虫,有这个内部多线程,就已经足够了。
最后是上面的类的一个测试的例子:
$urls = array("http://baidu.com", "http://baidu.com", "http://baidu.com", "http://baidu.com", "http://baidu.com", "http://baidu.com", "http://www.google.com", "http://www.sina.com.cn", );
$m = new Http_MultiRequest(); $t = microtime(true);
$m->setUrls($urls); //parallel fetch(并行抓取):
$data = $m->exec();
$parallel_time = microtime(true) - $t;
echo $parallel_time . "\n"; $t = microtime(true); //serial fetch(串行抓取):
foreach ($urls as $url)
{
$data[] = $m->execOne($url);
}
$serial_time = microtime(true) - $t;
echo $serial_time . "\n";
PHP多进程(4) :内部多进程的更多相关文章
- webpack 打包优化的四种方法(多进程打包,多进程压缩,资源 CDN,动态 polyfill)
如今,webpack 毫无疑问是前端构建领域里最耀眼的一颗星,无论你前端走哪条路线,都需要有很强的webpack 知识.webpack 的基本用法这里就不展开讲了.主要探讨一下如何提高 webpack ...
- 【多进程】php多进程编程
先看下我已经安装的php版本 PHP (cli) (built: Jul ::) ( NTS ) Copyright (c) - The PHP Group Zend Engine v3.- Zend ...
- Android开发中怎样用多进程、用多进程的好处、多进程的缺陷、解决方法(转)
转自:http://blog.csdn.net/spencer_hale/article/details/54968092 1.怎样用多进程 Android多进程概念:一般情况下,一个应用程序就是一个 ...
- swoole http_server 多进程并使用多进程处理消息
<?php $http = new swoole_http_server("0.0.0.0", 9511); $http->set([ 'worker_num' =&g ...
- PHP多进程初探 --- 利用多进程开发点儿东西吧
[原文地址:https://blog.ti-node.com/blog...] 干巴巴地叨逼叨了这么久,时候表演真正的技术了! 做个高端点儿的玩意吧,加入我们要做一个任务系统,这个系统可以在后台帮我们 ...
- 多进程浏览器、多线程页面渲染与js的单线程
线程与进程 说到单线程,就得从操作系统进程开始说起.在早期的操作系统中并没有线程的概念,进程是能拥有资源和独立运行的最小单位,也是程序执行的最小单位.任务调度采用的是时间片轮转的抢占式调度方式,而进程 ...
- Tornado实现多进程/多线程的HTTP服务
用tornado web服务的基本流程 实现处理请求的Handler,该类继承自tornado.web.RequestHandler,实现用于处理请求的对应方法如:get.post等.返回内容用sel ...
- Cpython解释器下实现并发编程——多进程、多线程、协程、IO模型
一.背景知识 进程即正在执行的一个过程.进程是对正在运行的程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一.操作系统的其他所有内容都 ...
- Tornado实现多线程、多进程HTTP服务
背景 线上有一个相关百科的服务,返回一个query中提及的百科词条.该服务是用python实现的,以前通过thrift接口访问,现要将其改为通过HTTP访问.之前没有搭建HTTPServer的经验,因 ...
随机推荐
- C++ 声明与引用
任何一个技术或者知识点,都是为了解决某个问题.也就是都有他的使用场景,或者说为什么搞出这种技术. 1.解决的问题:现实生活中的例子,要使用一个工具,必要把工具放在这里,或者说我有这个工具.工具只能放在 ...
- API的文件遍历,未使用CFileFind,因为里面牵扯MFC,编个DLL好麻烦。
// FindFileDebug.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include "FindFileDebug. ...
- send返回值
http://blog.csdn.net/anghlq/article/details/5990513 在Unix系统下,如果send . recv . write在等待协议传送数据时 , socke ...
- HDU 1595 find the longest of the shortest【次短路】
转载请注明出处:http://blog.csdn.net/a1dark 分析:经典的次短路问题.dijkstra或者SPFA都能做.先找出最短路.然后依次删掉没条边.为何正确就不证明了.了解思想直接A ...
- git gui :Updating the Git index failed. A rescan will be automatically started to res
这个是由于unix系统的换行符和windows的换行符不一致造成的结果.你在安装git的时候,设置了成使用LF,即unix换行符,可是你是在windows下进行文件编辑的,所以会出现上面的警告.其实这 ...
- 分享阿里云SLB-负载均衡的实现基本原理架构
负载均衡技术原理浅析 https://help.aliyun.com/knowledge_detail/39444.html?spm=5176.7839438.2.6.XBbX5l 阿里定制版的LVC ...
- 基于Java的在线聊天室
概述 Java socket编程,实现一个在线聊天室, 实现在线用户群聊,私聊,发送文件等功能. 详细 代码下载:http://www.demodashi.com/demo/13623.html 一. ...
- MySQL5.6 主从复制 ERROR 1776 (HY000): Parameters MASTER_LOG_FILE
主从都开启了gtid,在设置从库的时候遇到了问题 mysql> CHANGE MASTER TO MASTER_HOST=‘xxx’,MASTER_USER='replicant',MASTER ...
- 窗口管理器 Openbox 入门指南
2008-07-30 也许你听说过 Blackbox 和 Fluxbox,那么,Openbox 又是什么?Openbox 跟它们很相似.不过,我们还是来看看 Openbox 官方给出的说明吧.Op ...
- 【转帖】Service Discovery: 6 questions to 4 experts
https://highops.com/insights/service-discovery-6-questions-to-4-experts/ What’s Service Discovery? I ...