2011-06-21 9 views
10

To jest pętla używana w naszym skrypcie z lokami. To powoduje zużycie procesora do 100%. Znajomy powiedział: "Twój komputer tak szybko się zapętla, że ​​nie ma czasu na przetworzenie żądania, ponieważ stale sprawdza stan końcowy." ... Więc moje pytanie brzmi, jak można ponownie napisać tę pętlę, aby zwolnić? Dziękizrobić pętlę powodującą 100% użycie procesora z curl_multi_exec

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

Odpowiedz

0

Możesz dodać sleep(1), który śpi na jedną sekundę, w pętli.

+0

Czy chodziło Ci o "sen (1)"? –

2

Dodanie połączenia do http://php.net/sleep lub http://php.net/usleep w każdej iteracji powinno zmniejszyć użycie procesora, umożliwiając zaplanowanie innych uruchomionych procesów przez system operacyjny.

+0

sleep() nie ma wpływu na użycie procesora, żadnych innych myśli? – Anagio

+0

Jeśli wartość 1 lub 2 nie ma znaczenia, powinieneś sprawdzić http://php.net/manual/en/function.curl-multi-exec.php. Może musisz zamknąć kilka uchwytów lub coś podobnego. – webspy

+0

Problem ze snem polega na tym, że będzie blokował, nawet jeśli procesy zostaną zakończone. jeśli curl kończy się 0,1 sekundy po wywołaniu curl_multi_exec, musisz poczekać 0,9 lub 1,9 sekundy. –

2

Niestety nie pisać cały kod. Przypuszczam, że robisz coś takiego, jak:

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

Powinieneś zrozumieć, że jeszcze nie uruchamiałeś wątków. curl_multi_exec() uruchamia wszystkie wątki. Ale nie może jednocześnie uruchomić wszystkich wątków $ desiredThreadsNumber. Jeśli spojrzysz na przykład na stronie php.net curl_multi_exec(), zobaczysz, że musisz poczekać, aż curl_multi_exec() uruchomi wszystkie wątki. Innymi słowy, trzeba następny zagnieżdżonych pętli tutaj:

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

Na koniec pozwolę sobie zasugerować, aby przeczytać ten artykuł http://www.onlineaspect.com/2009/01/26/how-to-use-curl_multi-without-blocking/ i użyć fragmentu kodu stamtąd, użyłem go w 2 lub 3 projektów.

0

Spróbuj:

$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) rzeczywiście jest droga, ale istnieje kilka ostrzeżenia.

Po pierwsze, jeśli curl_multi_exec zwraca CURLM_CALL_MULTI_PERFORM, ma więcej danych do przetworzenia natychmiast, więc powinno zostać uruchomione ponownie. Ważne jest również sprawdzenie, czy curl_multi_exec nie zawiodło natychmiast; w takim przypadku curl_multi_select może blokować na zawsze.

To powinno działać:

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

Jeśli ktoś widzi to dobry sposób, aby uniknąć while (true) bez kodu powielania, należy skierować go na zewnątrz.

1

Próbowałem wszystkich rozwiązań przewidzianych powyżej, ale ten pracował dla mnie w systemie silnie obciążonej gdzie na każdy drugi występuje więcej niż 1k Wielu Curl wnioski są wykonane.

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