为了更好的服务!分享
热搜:最后的问候

全站

    广告位置
    • 总篇数 (0)
    • 粉丝量 (3)

    php实现并发处理之curl篇

    • 2018-07-15 11:28:44
    • 来源:ctocode
    • 阅读量:902
    • 收藏:0
    • 被赞:0
    • 作者:
    php/

    用手机看

    扫描二维码随身看资讯 使用手机 二维码应用 扫描右侧二维码,您可以
    1.在手机上细细品读~
    2.分享给你的微信好友或朋友圈~

    摘要

    原文地址:https://yq.aliyun.com/articles/27416?spm=5176.8091938.0.0.yloNYW

    https://blog.csdn.net/lg_lin/article/details/51944115

    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( 
        'http://www.example.com', 
        'http://www.example.net', 
    )));

    下面是边请求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"]."
    ";
        } else {
            echo $data["url"]." -- ".$data["error"]."
    ";
        }
    }
    $urls = array();
    for ($i = 0; $i < 10; $i++) {
        $urls[] = 'http://www.baidu.com/s?wd=etao_'.$i;
        $urls[] = 'http://www.so.com/s?q=etao_'.$i;
        $urls[] = 'http://www.soso.com/q?w=etao_'.$i;
    }
    curl($urls, "deal");

    注释:

    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方法比较耗时的话,那整体会非常耗时。


    转载请注明本网站 https://www.10yun.com/      谢谢~

    如有不懂得,可到底部【给我留言】联系站长QQ~

    微信扫一扫,看资讯
    aaa

    扫二维码或搜索微信公众号“十云“关注
    回复” 技术分享、职位、新闻、工作 “即可查看最新相关内容!
    赶快扫一扫吧~

    表羞涩嘛~喜欢就点我

    0

    分享吧~~:

    祝给予赞赏的伙伴,2019年发大财!

    相关阅读

    热门商品

    更多+

    剩余: 89 /299 有效日期:2014-12-31

    查看

    精彩专题
    • xxx独家授权礼包

    合作伙伴