鍍金池/ 問(wèn)答/PHP/ PHP下curl_multi執(zhí)行一直停不下來(lái)

PHP下curl_multi執(zhí)行一直停不下來(lái)

莫名其妙,CPU負(fù)責(zé)特別高。而且下面代碼執(zhí)行的Job執(zhí)行了好幾天,硬是沒(méi)有結(jié)束。為什么程序會(huì)結(jié)束不了?

整個(gè)代碼里就只有這個(gè)循環(huán),所以應(yīng)該是下面的do-while沒(méi)有結(jié)束的問(wèn)題。但為什么會(huì)結(jié)束不了呢?我懷疑是running 始終大于0。會(huì)有這種情況嗎?

<?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]);
    }
    
    //這里有個(gè)循環(huán)
    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);
}

對(duì)比官方參考的代碼:

$active = null;

// 執(zhí)行批處理句柄
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);
    }
}

做了如下推斷:

  1. 對(duì)單個(gè)curl沒(méi)有設(shè)置請(qǐng)求的過(guò)期時(shí)間。但是php都默認(rèn)設(shè)置了超時(shí)時(shí)間。所以這個(gè)是不應(yīng)該的。
  2. 對(duì)比官方推薦的代碼,其實(shí)running 都是作為程序判斷邏輯的。只是官方推薦的代碼,嚴(yán)格按照libcurl來(lái)執(zhí)行。
  3. curl_multi通過(guò)select()還是poll()的方式做調(diào)用,我先不做區(qū)分。但我理解這種方式,等價(jià)于一個(gè)長(zhǎng)輪詢,所以CPU消耗的比較客觀。

請(qǐng)大家?guī)兔Ψ治龇治?/p>

回答
編輯回答
厭惡我

curl代碼中的curl_multi_perform函數(shù)來(lái)說(shuō),如果是CURLM_BAD_HANDLE,或者CURLM_RECURSIVE_API_CALL的情況下,是沒(méi)有機(jī)會(huì)去更新
*running_handles = multi->num_alive;
這時(shí)候如果只判斷了running,則會(huì)陷入死循環(huán)。
官方給的代碼,只會(huì)在返回值為CURLM_OK或者CURLM_CALL_MULTI_PERFORM的情況下循環(huán)。

那我來(lái)大膽蒙一下:如果通過(guò)curl_multi_init()創(chuàng)建mh后 && 請(qǐng)求結(jié)束前,由于網(wǎng)絡(luò)等原因?qū)е耺h失效、連接斷開(kāi)等,會(huì)導(dǎo)致上述死循環(huán)。

2018年4月13日 20:12
編輯回答
傲嬌范

額,既然懷疑,就把$running打到log里去看看唄,不然你發(fā)上來(lái)也看不出$running是啥啊。。。

2018年3月31日 17:38