ホームページ >バックエンド開発 >PHPチュートリアル >ストリーミング モードでのマルチスレッド収集に関連する問題。専門家に分析を依頼してください。

ストリーミング モードでのマルチスレッド収集に関連する問題。専門家に分析を依頼してください。

WBOY
WBOYオリジナル
2016-06-13 13:09:17854ブラウズ

ストリーミングモードでのマルチスレッド収集の問題、専門家に分析してください
コンテンツの収集速度が遅いので、最近マルチスレッド収集について研究しています。 以下に比較コードを掲載します。問題は 2 つあります。1 つは、得られる結果の長さが少し矛盾していることです。2 つ目は、効率が十分ではないことです。皆さんも分析とテストにご協力ください!

PHP コード
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->
<?php
$timeStart = microtimeFloat();
function microtimeFloat() {
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}
$data = '';
$urls = array('http://www.tzksgs.com/news/2012-09/article-217.html', 'http://www.tzksgs.com/news/2012-09/article-219.html', 'http://www.tzksgs.com/news/2012-09/article-222.html');
foreach($urls as $url){
    echo strlen(file_get_contents($url)),'<br>';
}
$timeEnd = microtimeFloat();
echo sprintf("Spend time: %s second(s)\n", $timeEnd - $timeStart),'<br>';
$timeStart = microtimeFloat();
$timeout = 30;
$status = array();
$retdata = array();
$sockets = array();
$userAgent = $_SERVER['HTTP_USER_AGENT'];
foreach($urls as $id => $url) {
    $tmp = parse_url($url);
    $host = $tmp['host'];
    $path = isset($tmp['path'])?$tmp['path']:'/';
    empty($tmp['query']) or $path .= '?' . $tmp['query'];
    if (empty($tmp['port'])) {
        $port = $tmp['scheme'] == 'https' ? 443 : 80;
    } else $port = $tmp['port'];
    $fp = stream_socket_client("$host:$port", $errno, $errstr, 30);
    if (!$fp) {
        $status[$id] = "failed, $errno $errstr";
    } else {
        $status[$id] = "in progress";
        $retdata[$id] = '';
        $sockets[$id] = $fp;
        fwrite($fp, "GET $path HTTP/1.1\r\nHost: $host\r\nUser-Agent: $userAgent\r\nConnection: Close\r\n\r\n");
    }
}
// Now, wait for the results to come back in

while (count($sockets)) {
    $read = $write = $sockets;
    //This is the magic function - explained below
    if (stream_select($read, $write = null, $e = null, $timeout)) {
        //readable sockets either have data for us, or are failed connection attempts
        foreach ($read as $r) {
            $id = array_search($r, $sockets);
            $data = fread($r, 8192);
            if (strlen($data) == 0) {
                if ($status[$id] == "in progress") {
                    $status[$id] = "failed to connect";
                }
                fclose($r);
                unset($sockets[$id]);
            } else {
                $retdata[$id] .= $data;
            }
        }
    }
}
foreach($retdata as $data){
    $data = trim(substr($data, strpos($data, "\r\n\r\n") + 4));
    echo strlen($data),'<br>';
}
$timeEnd = microtimeFloat();
echo sprintf("Spend time: %s second(s)\n", $timeEnd - $timeStart);
?>



-----解決策---------------- - ---
あなたはcurl_multi_....を試すことができます。 同時実行
これにより、上記の2人が言及した問題と同様に、php命令の数を可能な限り減らすことができます。それは間違いなく PHP で解決できるものではありません

------解決策------------------
もちろん、file_get_contents() はブロックしています。複数のクロール タスクを実行すると、当然ながら遅くなります。
socket_*()、fsockopen()、stream_*() はすべてノンブロッキングです。
------解決策-----
どれくらい遅いですか?

これを追加してみてください:

$context = stream_context_create(array('http' => array('header'=>'Connection: close')));
file_get_contents(". ... .",false,$context);
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。