Do while, вызывающий 100% использование ЦП с curl_multi_exec

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

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

Ответ 2

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

Ответ 3

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

$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() запускает все потоки. Но он не может одновременно запускать все $requiredThreadsNumber. Если вы посмотрите, например, на странице 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 проектов.

Ответ 4

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) без дублирования кода, укажите его.

Ответ 5

Пробовал все решения, приведенные выше, но этот работал у меня в высоконагруженной системе, где в каждую секунду выполняется более 1 тыс. запросов 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);
}

Ответ 6

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

Ответ 7

Try:

 $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 );