鍍金池/ 問答/PHP/ PHP下curl_multi執(zhí)行一直停不下來

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

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

整個(gè)代碼里就只有這個(gè)循環(huán),所以應(yīng)該是下面的do-while沒有結(jié)束的問題。但為什么會(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沒有設(shè)置請(qǐng)求的過期時(shí)間。但是php都默認(rèn)設(shè)置了超時(shí)時(shí)間。所以這個(gè)是不應(yīng)該的。
  2. 對(duì)比官方推薦的代碼,其實(shí)running 都是作為程序判斷邏輯的。只是官方推薦的代碼,嚴(yán)格按照libcurl來執(zhí)行。
  3. curl_multi通過select()還是poll()的方式做調(diào)用,我先不做區(qū)分。但我理解這種方式,等價(jià)于一個(gè)長(zhǎng)輪詢,所以CPU消耗的比較客觀。

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

回答
編輯回答
厭惡我

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

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

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

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

2018年3月31日 17:38