欢迎来到[自学php网] ①群 AG亚游集团

AG亚游集团 > php专栏 > php综合实列 >

php实现并发处理之curl篇

来源:未知 ?? 时间:2019-07-14 10:49?作者:小飞侠

[导读] php在并发处理方面的确不如java好。但是也有一些方法可以实现并发处理。比如使用curl就可以实现url的并发请求。 看到网上有人说使用curl会导致阻塞,即所有的请求数据都获取完毕后一...

php在并发处理方面的确不如java好。但是也有一些方法可以实现并发处理。比如使用curl就可以实现url的并发请求。

看到网上有人说使用curl会导致阻塞,即所有的请求数据都获取完毕后一并返回,然后再进行数据处理。而不是获取一个请求的数据就处理一个数据。其实这种说法是不对的,只能说明他在代码实现上有问题。

在php官方找了段导致阻塞的示例代码,如下:

function multiple_threads_request($nodes){ 
        $mh = curl_multi_init(); 
        $curl_array = array(); 
        foreach($nodes as $i => $url) 
        { 
            $curl_array[$i] = curl_init($url); 
            curl_setopt($curl_array[$i], CURLOPT_RETURNTRANSFER, true); 
            curl_multi_add_handle($mh, $curl_array[$i]); 
        } 
        $running = NULL; 
        do { 
            usleep(10000); 
            curl_multi_exec($mh,$running); 
        } while($running > 0); 
         
        $res = array(); 
        foreach($nodes as $i => $url) 
        { 
            $res[$url] = curl_multi_getcontent($curl_array[$i]); 
        } 
         
        foreach($nodes as $i => $url){ 
            curl_multi_remove_handle($mh, $curl_array[$i]); 
        } 
        curl_multi_close($mh);        
        return $res; 
} 
print_r(muti_thread_request(array( 
    '/wwwaff4exampleaff4com', 
    '/wwwaff4exampleaff4net', 
)));

下面是边请求url,边处理返回数据的示例代码:


/*
 * @purpose: 使用curl并行处理url
 * @return: array 每个url获取的数据
 * @param: $urls array url列表
 * @param: $callback string 需要进行内容处理的回调函数。示例:func(array)
 */
function curl($urls = array(), $callback = '')
{
    $response = array();
    if (empty($urls)) {
        return $response;
    }
    $chs = 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($chs, $ch);
        $map[strval($ch)] = $url;
    }
    do{
        if (($status = curl_multi_exec($chs, $active)) != CURLM_CALL_MULTI_PERFORM) {
            if ($status != CURLM_OK) { break; } /如果没有准备就绪,就再次调用curl_multi_exec
            while ($done = curl_multi_info_read($chs)) {
                $info = curl_getinfo($done["handle"]);
                $error = curl_error($done["handle"]);
                $result = curl_multi_getcontent($done["handle"]);
                $url = $map[strval($done["handle"])];
                $rtn = compact('info', 'error', 'result', 'url');
                if (trim($callback)) {
                    $callback($rtn);
                }
                $response[$url] = $rtn;
                curl_multi_remove_handle($chs, $done['handle']);
                curl_close($done['handle']);
                /如果仍然有未处理完毕的句柄,那么就select
                if ($active > 0) {
                    curl_multi_select($chs, 0.5); /此处会导致阻塞大概0.5秒。
                }
            }
        }
    }
    while($active > 0); /还有句柄处理还在进行中
    curl_multi_close($chs);
    return $response;
}
 
/使用方法
function deal($data){
    if ($data["error"] == '') {
        echo $data["url"]." -- ".$data["info"]["http_code"]."\n";
    } else {
        echo $data["url"]." -- ".$data["error"]."\n";
    }
}
$urls = array();
for ($i = 0; $i < 10; $i++) {
    $urls[] = '/wwwaff4baiduaff4com/s?wd=etao_'.$i;
    $urls[] = '/wwwaff4soaff4com/s?q=etao_'.$i;
    $urls[] = '/wwwaff4sosoaff4com/q?w=etao_'.$i;
}
curl($urls, "deal");



演示网址 /demoaff4bo56aff4com/bigpipe/


注释:

1.关于curl_multi_exec函数的返回值:

返回CURLM_CALL_MULTI_PERFORM 说明curl_multi_exec需要马上被再调用一次。

返回CURLM_OK 说明已经有需要处理的数据。这时你需要进行相关处理,处理完后再次调用curl_multi_exec。

php中的curl_multi_exec是调用的curl库中的curl_multi_perform方法。代码在multi.c的230行左右。


2.此方式,虽然在获取数据和数据处理上是并行的,但是在数据处理时依然是串行的。即数据是一条条依次处理的。如果deal方法比较耗时的话,那整体会非常耗时。


最新文章

点击排行

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号@版权所有AG亚游集团

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

黑龙江鹤岗至辽宁大连高速一隧道货车侧翻(图) 女子称被章文性侵遭威胁:你败坏老子名誉 走着瞧 沪台体育交流 世界冠军王仪涵点拨台北小球员 2018纽约围棋盛会暨首届北美高校赛圆满落幕 苹果抛压沉重 铁矿石不宜追空 外国专家评中国模式:让人民幸福的制度才是好制度 中金:美国调查华为与中兴不同 或影响全球产业链 发改委:汽油柴油每吨分别上调170元和165元 广西强降雨致3死1失踪 多地发布气象灾害预警 涉嫌挟持玩家电脑“挖矿”:一独立游戏遭Steam下架 三连败+输6分战一方逼近悬崖 卡拉斯科是还魂丹吗 俄苏57部署叙利亚:展示决心建立威慑 向各方示强
科学家警告:远离外星人 人类科技落后他们太多 陈志钊:打不开局面时全队很耐心 远射进球很幸运 韩国JTBC杯李世石执黑胜许映皓 夺个人第50冠 媒曝李佼辞去荷兰队教练职务 决定回国陪伴家人 富士康IPO三亿承销费花落中金 大投行洗牌加剧 老板酒驾致老人死亡 逃逸后找下属顶替被交警识破 台男星强吻搭档女记者 抬头问:再一个? 延边宣布K联赛射手加盟披10号 上赛季1人造19球 公交司机免费发二百多件雨衣:用公司奖励买的(图) 丈夫酒驾撞车与妻子换座位 夫妻一条心欺瞒交警 吸毒男女生下女婴:女方去世 男方涉遗弃罪被公诉 美国高尔夫参与人数略有上涨 拉动经济841亿美元
台媒:精英出走是对台当局拼政治的无言抗议 腾讯总裁刘炽平:支付领域对手提供高补贴 我们将跟进 男子偷车被发现后跳河 路人拉其上岸:救人要紧 9岁小学生沉迷手游 手机被家长藏起后放言要拆家 巴萨主帅:已看惯梅西的表演 但他还能让人惊讶 日媒:这次安倍母亲急了 恐将儿媳妇“逐出家门” 三部门:对失信被执行人实施限制不动产交易惩戒 环球时报评特朗普挑起贸易战:得道多助 失道寡助 巴勒斯坦代表谈边境冲突:对安理会“瘫痪”很遗憾 投资小型加工厂 一万元猪舍建设图片 手机挂机软件一小时5元 白手起家做什么好 AG亚游集团