Ответ 1
Попробуйте следующее: http://php.net/manual/function.curl-multi-select.php
Это цикл, используемый в нашем script с curl. Это заставляет процессор использовать до 100%. Друг сказал: "Ваш компьютер так быстро зацикливается, что у него нет времени на обработку запроса, так как он постоянно проверяет окончание". Итак, мой вопрос в том, как этот цикл можно переписать для замедления? Благодаря
$running = null;
do {
curl_multi_exec($mh, $running);
} while($running > 0);
Попробуйте следующее: http://php.net/manual/function.curl-multi-select.php
Добавление вызова http://php.net/sleep или http://php.net/usleep на каждой итерации должно уменьшать использование ЦП, позволяя другим рабочим процессам планировать операционную систему.
К сожалению, вы не опубликовали весь код. Я полагаю, вы делаете что-то вроде
$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 проектов.
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) без дублирования кода, укажите его.
Пробовал все решения, приведенные выше, но этот работал у меня в высоконагруженной системе, где в каждую секунду выполняется более 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);
}
Вы можете добавить sleep(1)
, который спит в течение одной секунды, в цикл.
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 );