цикл while, вызывающий 100% загрузку процессора с помощью curl_multi_exec - PullRequest
10 голосов
/ 21 июня 2011

Это цикл, используемый в нашем скрипте с curl.Это вызывает загрузку процессора до 100%.Один из друзей сказал: «Ваш компьютер зацикливается так быстро, что у него нет времени на обработку запроса, поскольку он постоянно проверяет окончание». Итак, мой вопрос: как можно переписать этот цикл, чтобы замедлить его?Спасибо

$running = null;
do {
  curl_multi_exec($mh, $running);
} while($running > 0);

Ответы [ 7 ]

8 голосов
/ 21 июня 2011
2 голосов
/ 22 июня 2011

К сожалению, вы не опубликовали весь код.Я полагаю, вы делаете что-то вроде

$mh = curl_multi_init();
for ($i = 0; $i < $desiredThreadsNumber; $i++) {
    $ch = curl_init();
    // set up $ch here
    curl_multi_add_handle($mh, $ch);
}

Вы должны понимать, что вы еще не запускали потоки здесь. curl_multi_exec () запускает все потоки.Но он не может запускать все потоки $ wantedThreadsNumber одновременно.Если вы посмотрите пример на странице curl_multi_exec () php.net, вы увидите, что вам нужно подождать, пока curl_multi_exec () запустит все потоки.Другими словами, вам нужен следующий вложенный цикл:

$running = null;
do {
    do {
        $mrc = curl_multi_exec($mh, $running);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
} while($running > 0);

В конце позвольте мне предложить вам прочитать эту статью http://www.onlineaspect.com/2009/01/26/how-to-use-curl_multi-without-blocking/ и использовать оттуда фрагмент кода, я использовал его в 2 или3 проекта.

2 голосов
/ 21 июня 2011

Добавление вызова к http://php.net/sleep или http://php.net/usleep в каждой итерации должно снизить загрузку ЦП, позволяя операционной системе планировать другие запущенные процессы.

1 голос
/ 23 июня 2016

Перепробовал все решения, представленные выше, но это сработало для меня в сильно загруженной системе, где каждую секунду поступает более 1k запросов Multi Curl.

//Execute Handles
$running = null;

do {
    $mrc = curl_multi_exec($mh, $running);
} while($mrc == CURLM_CALL_MULTI_PERFORM);

while ($running && $mrc == CURLM_OK) {
    if (curl_multi_select($mh) == -1) {
        usleep(1);
    }
    do {
        $mrc = curl_multi_exec($mh, $running);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
1 голос
/ 02 марта 2013

curl_multi_select (http://php.net/manual/function.curl-multi-select.php) - действительно путь, но есть пара предостережений.

Во-первых, если curl_multi_exec возвращает CURLM_CALL_MULTI_PERFORM, у него есть больше данных, которые должны быть обработаны немедленно, поэтому должноЗапустите снова. Также важно проверить, что curl_multi_exec не сразу завершился ошибкой, в этом случае curl_multi_select может заблокироваться навсегда.

Это должно работать:

do {
    while (CURLM_CALL_MULTI_PERFORM === curl_multi_exec($mh, $running)) {};
    if (!$running) break;
    while (curl_multi_select($mh) === 0) {};
} while (true);

Если кто-нибудь видит хороший способчтобы избежать while (true) без дублирования кода, укажите это.

0 голосов
/ 28 октября 2012

Попробуйте:

 $running = null;
    do {
        do {
            $mrc = curl_multi_exec($mh, $running);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM && curl_multi_select($mh) === 0 );
    } while($running > 0  && $mrc == CURLM_OK );
0 голосов
/ 21 июня 2011

Вы можете добавить sleep(1), который спит одну секунду, в цикл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...