curl_multi实现准多线程采集

来源:互联网 发布:amd处理器优化 编辑:程序博客网 时间:2024/05/16 11:52
<?php$urls = array(   'task1' => "http://localhost/sleep1.php", // sleep(1) 后返回   'task2' => "http://localhost/sleep2.php", // sleep(2) 后返回 );$mh = curl_multi_init();foreach ($urls as $key => $url) {    $ch = curl_init($url);    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);    curl_multi_add_handle($mh, $ch);    // 资源id,用以标识请求    $id = (int)$ch;    // 回调函数    $task[$id]['callback'] = function($content)use($key) {        echo $content;        // 请求返回后创建文件,并记录时间        file_put_contents($key, time());    };}do{    // 执行    $status = curl_multi_exec($mh, $active);    // 避免cpu使用率过高    if ($active && curl_multi_select($mh) === -1)         usleep(250);    // 等待请求返回    while($done = curl_multi_info_read($mh)) {        $id = (int)$done['handle'];        // 读取返回        $content = curl_multi_getcontent($done['handle']);        // 执行回调函数        $task[$id]['callback']($content);    }}while ($status === CURLM_CALL_MULTI_PERFORM || $active);

文件task2的创建时间比task1迟1秒,说明两个请求是并发的。
如果使用curl单线程循环发送请求,必须等待task1请求完毕,执行完回调后,再发送task2请求。
由于curl_multi是多线程的,两个请求同时发送,task1先返回后会马上执行回调函数,同时等待task2返回。如果有多个采集任务,这样可以节省很多时间。

但即使这样也只能实现“准多线程”。

// 将回调函数修改function($content)use($key) {        echo $content;        // 请求返回后创建文件,并记录时间        file_put_contents($key, time());        // 加上这句        if($key == 'task1')            sleep(3);    };

task2文件创建时间比task1迟3秒,说明task1的回调函数阻塞了task2回调的执行。

curl_multi在其内部实现了多线程发送请求,但在php代码层面仍然是单线程阻塞的。

1 0
原创粉丝点击