本片文章向大家介紹了關於php的set_time_out和max_execution_time設置,有需要的朋友可以參考。
#想讓一個php腳本(fpm或cli下)透過set_time_out或max_execution_time設定只執行5秒。
<?phpini_set("max_execution_time",5); set_time_limit(5);for($i=0;$i<=10;$i++) {echo $i."\n"; sleep(1); }
012345678910
fpm也是一樣。
首先看手冊函數啊,摘超如下:
set_time_limit()函數和設定指令max_execution_time只會影響腳本本身執行的時間。任何發生在諸如使用system()的系統調用,流操作,資料庫操作等的腳本執行的最大時間不包括其中,當該腳本已運行時。在測量時間是實值的Windows中,情況就不是如此了。
仍然是一臉懵逼。
另外看到另外一句:
當php運行於安全模式時,此功能不能生效。除了關閉安全模式或改變php.ini中的時間限制,沒有別的辦法
特地看了一眼,不是安全模式啊。 。
然後百思不得,得到了大官人的耐心解答。
php zend引擎實作max_execute_time是使用的settimer,參數是ITIMER_PROF(也就是說這只計算用戶態和內核態使用的真正消耗的時間)
但是sleep是掛起進程一段時間,並沒有執行操作,也不存在消耗時間,所以這個sleep既不消耗核心態時間也不消耗使用者態時間。
寫了段C程式驗證了一下,確實在sleep狀態下,根本沒有時間統計,也不會觸發signal handler..
那我追一下這個[ITIMER_PRO][3 ]F
參數
Description
The system provides each process with three interval timers, each decrementing in a distinct time domain. When any timer expires, a signal is sent to the process, and the timer ( potentially) restarts.
ITIMER_REAL
decrements in real time, and delivers SIGALRM upon expiration.
ITIMER_VIRTUAL
decrements only 非expiration.
ITIMER_PROF
decrements both when the process executes and when the system is executing on behalf of the process. Coupled with ITIMER_VIRTUAL, this timer is usually used pfileby in user and kernel space. SIGPROF is delivered upon expiration.
#看ITIMER_PROF選項中process executes 不就是php進程執行嗎?是進程執行沒問題,但是sleep函數會將進程掛起,所以sleep內的不算了。所以,在使用者態執行的時間,是除開你sleep後的所有時間
果真有具體差別,那麼源碼中具體怎樣體現的?再追一下
再main.c
下追到以下
/* {{{ proto bool set_time_limit(int seconds) Sets the maximum time a script can run */PHP_FUNCTION(set_time_limit) { zend_long new_timeout; char *new_timeout_str; int new_timeout_strlen; zend_string *key; if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &new_timeout) == FAILURE) { return; } new_timeout_strlen = (int)zend_spprintf(&new_timeout_str, 0, ZEND_LONG_FMT, new_timeout); key = zend_string_init("max_execution_time", sizeof("max_execution_time")-1, 0); if (zend_alter_ini_entry_chars_ex(key, new_timeout_str, new_timeout_strlen, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0) == SUCCESS) { RETVAL_TRUE; } else { RETVAL_FALSE; } zend_string_release(key); efree(new_timeout_str); }
我們看key那一行的sizeof("max_execution_time")
然後追一下max_execution_time
還是再main.c下,有
} if (PG(max_input_time) != -1) {#ifdef PHP_WIN32 zend_unset_timeout();#endif zend_set_timeout(INI_INT("max_execution_time"), 0); }
然後再zend目錄下搜尋zend_set_timeout,然後再zend_execute_api.c找到ITIMER_PROF
以上是php的set_time_out和max_execution_time設定的詳細內容。更多資訊請關注PHP中文網其他相關文章!