The execution of curl_multi can not be stopped under PHP.

inexplicably, CPU is particularly responsible. And the Job executed by the following code has been executed for several days, but it is not finished. Why can"t the program end?

this loop is the only one in the entire code, so it should be the unfinished problem of do-while below. But why can"t it end? I suspect that running is always greater than 0. Will this happen?

<?php
public function run()
{
    $mh = curl_multi_init();
    foreach ($this->_serverList as $key => $hostname) {

        $url = "http://{$hostname}:8360/MonitorInterfaceJob.php?interval=" . $this->_timeInterval;
        $ch[$key] = curl_init($url);
        curl_setopt($ch[$key], CURLOPT_HEADER, 0);
        curl_setopt($ch[$key], CURLOPT_RETURNTRANSFER, true);

        curl_multi_add_handle($mh, $ch[$key]);
    }
    
    //
    do {
        curl_multi_exec($mh, $running);
    } while ($running > 0);

    foreach ($this->_serverList as $key => $hostname) {
        curl_multi_remove_handle($mh, $ch[$key]);
    }

    curl_multi_close($mh);
}

compare the official reference code:

$active = null;

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

while ($active && $mrc == CURLM_OK) {
    if (curl_multi_select($mh) != -1) {
        do {
            $mrc = curl_multi_exec($mh, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
}

made the following inference:

  1. does not set the expiration time of the request for a single curl. However, php sets the timeout by default. So this should not be done.
  2. compared with the officially recommended code, running is actually used as program judgment logic. It"s just officially recommended code, which is strictly executed according to libcurl .
  3. curl_multi make calls via select () or poll () , I won"t make a distinction. But I understand that this approach is equivalent to a long poll, so the CPU consumption is more objective.

Please help me analyze

Php
Mar.01,2021

well, if you doubt it, type $running into log to have a look, or you won't see what $running is when you post it.


look at the curl_multi_perform function in curl code . In the case of CURLM_BAD_HANDLE, or CURLM_RECURSIVE_API_CALL, there is no opportunity to update
* running_handles = multi- > num_alive;
if only running, is judged, it will fall into a dead loop.
the official code will only loop if the return value is CURLM_OK or CURLM_CALL_MULTI_PERFORM.

Let me be bold: if the mh is created through curl_multi_init () & before the request ends, the mh fails or the connection is disconnected due to network and other reasons, which will lead to the above endless cycle .

MySQL Query : SELECT * FROM `codeshelper`.`v9_news` WHERE status=99 AND catid='6' ORDER BY rand() LIMIT 5
MySQL Error : Disk full (/tmp/#sql-temptable-64f5-1b3bde3-2c2d5.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
MySQL Errno : 1021
Message : Disk full (/tmp/#sql-temptable-64f5-1b3bde3-2c2d5.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
Need Help?