2011-06-21 8 views
10

Este es un bucle utilizado en nuestro script con curl. Está causando que el uso de la CPU se dispare al 100%. Un amigo dijo "Tu computadora está girando tan rápido aquí que no tiene tiempo para procesar la solicitud, ya que está constantemente buscando un final". Entonces, mi pregunta es ¿cómo se puede volver a escribir este ciclo para reducir la velocidad? Graciashacer mientras que el bucle provoca 100% de uso de CPU con curl_multi_exec

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

Respuesta

0

Se podría añadir sleep(1), que duerme durante un segundo, en el bucle.

+0

¿Quisces decir 'sleep (1)'? –

2

Agregar una llamada a http://php.net/sleep o http://php.net/usleep en cada iteración debe reducir el uso de la CPU al permitir que otros procesos en ejecución sean programados por el sistema operativo.

+0

sleep() no está teniendo un efecto en el uso de la CPU, ¿algún otro pensamiento? – Anagio

+0

Si un valor de 1 o 2 no hace ninguna diferencia, entonces debe investigar http://php.net/manual/en/function.curl-multi-exec.php. Tal vez tengas que cerrar algunos mangos o algo similar. – webspy

+0

el problema con el sueño es que bloqueará incluso si los procesos han finalizado. si curl termina 0.1 segundo después de llamar a curl_multi_exec tienes que esperar 0.9 o 1.9 segundos. –

2

Desafortunadamente no CÓD.POSTAL conjunto. Supongo que está haciendo algo como

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

Debe comprender que todavía no ha ejecutado subprocesos aquí. curl_multi_exec() ejecuta todos los hilos. Pero no puede ejecutar todos los hilos $ desiredThreadsNumber simultáneamente. Si observa un ejemplo en la página curl_multi_exec() de php.net, verá que debe esperar mientras curl_multi_exec() ejecuta todos los hilos. En otras palabras, necesita siguiente bucle anidado aquí:

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

Al final me deja sugiero que lea este artículo http://www.onlineaspect.com/2009/01/26/how-to-use-curl_multi-without-blocking/ y utilizar fragmento de código a partir de ahí, lo usé en 2 o 3 proyectos.

0

Probar:

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

curl_multi_select (http://php.net/manual/function.curl-multi-select.php) es de hecho el camino a seguir, pero hay un par de advertencias.

En primer lugar, si curl_multi_exec devuelve CURLM_CALL_MULTI_PERFORM, tiene más datos para procesar de inmediato, por lo que debe ejecutarse de nuevo. Además, es importante comprobar que curl_multi_exec no falló inmediatamente; en ese caso, curl_multi_select podría bloquear para siempre.

Esto debería funcionar:

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

Si alguien ve una buena manera de evitar el while (true) sin duplicar código, por favor señalarlo.

1

Probé todas las soluciones proporcionadas anteriormente, pero esta funcionó para mí en un sistema altamente cargado en el que en cada segundo se realizan más de 1k peticiones de Curl múltiple.

//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); 
} 
Cuestiones relacionadas