if
(curl_multi_select(
$queue
, 0.5) != -1) {
do
{
$mrc
= curl_multi_exec(
$queue
,
$active
);
}
while
(
$mrc
== CURLM_CALL_MULTI_PERFORM);
}
}
$responses
=
array
();
foreach
(
$map
as
$url
=>
$ch
) {
$responses
[
$url
] = callback(curl_multi_getcontent(
$ch
),
$delay
);
curl_multi_remove_handle(
$queue
,
$ch
);
curl_close(
$ch
);
}
curl_multi_close(
$queue
);
return
$responses
;
}
首先将所有的
URL 压入并发队列, 然后执行并发过程, 等待所有请求接收完之后进行数据的
解析等后续处理
. 在实际的处理过程中, 受网络传输的影响, 部分 URL 的内容会优先于其他
URL 返回, 但是经典 cURL 并发必须等待最慢的那个 URL 返回之后才开始处理, 等待也就意
味着
CPU 的空闲和浪费. 如果 URL 队列很短, 这种空闲和浪费还处在可接受的范围, 但如果
队列很长
, 这种等待和浪费将变得不可接受.
2. 改进的 Rolling cURL 并发方式
仔细分析不难发现经典
cURL 并发还存在优化的空间, 优化的方式时当某个 URL 请求完毕
之后尽可能快的去处理它
, 边处理边等待其他的 URL 返回, 而不是等待那个最慢的接口返回
之后才开始处理等工作
, 从而避免 CPU 的空闲和浪费. 闲话不多说, 下面贴上具体的实现:
代码如下
:
function
rolling_curl(
$urls
,
$delay
) {
$queue
= curl_multi_init();
$map
=
array
();
foreach
(
$urls
as
$url
) {
$ch
= curl_init();
curl_setopt(
$ch
, CURLOPT_URL,
$url
);
curl_setopt(
$ch
, CURLOPT_TIMEOUT, 1);
curl_setopt(
$ch
, CURLOPT_RETURNTRANSFER, 1);
curl_setopt(
$ch
, CURLOPT_HEADER, 0);
curl_setopt(
$ch
, CURLOPT_NOSIGNAL, true);
curl_multi_add_handle(
$queue
,
$ch
);