摘要:任何發生在諸如使用的系統調用,流操作,數據庫操作等的腳本執行的最大時間不包括其中,當該腳本已運行。另外看到另外一句當運行于安全模式時,此功能不能生效。除了關閉安全模式或改變中的時間限制,沒有別的辦法特地看了一眼,不是安全模式啊。。
本意
想讓一個php腳本(fpm或者cli下)通過set_time_out或者max_execution_time設置只執行5秒。
我原想是這樣的代碼但是cli下結果是0 1 2 3 4 5 6 7 8 9 10fpm也一樣。
思考之路首先看手冊函數啊,摘超如下:
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..那我追一下這個settimer函數
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 when the process is executing, and delivers SIGVTALRM upon 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 to profile the time spent by the application 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
就是他了!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/28505.html
摘要:在使用時,經常會碰到和錯誤,下面以來分析下這兩種常見錯誤的原因和解決方案。錯誤在和中分別有這樣兩個配置項和。這兩項都是用來配置一個腳本的最大執行時間的。此外要注意的是的模塊中的和兩項。 在使用Nginx時,經常會碰到 502 Bad Gateway 和 504 Gateway Time-out 錯誤,下面以 Nginx+PHP-FPM 來分析下這兩種常見錯誤的原因和解決方案。 1. ...
摘要:的毫秒級超時也有問題。。中超時實現一初級最簡單的超時實現秒級超時思路很簡單鏈接一個后端,然后設置為非阻塞模式,如果沒有連接上就一直循環,判斷當前時間和超時時間之間的差異。實際處理這個調用的部件在完成后,通過狀態通知和回調來通知調用者。 概述 在PHP開發中工作里非常多使用到超時處理到超時的場合,我說幾個場景: 異步獲取數據如果某個后端數據源獲取不成功則跳過,不影響整個頁面展現 為了保...
摘要:另外,可以在腳本的最后調用輸出當前腳本小號的最大內存量。根據分配的內存總量來估算進程數。該擴展用于緩存操作碼。默認情況下,駐留的字符串會隔離在各個進程中。檢查腳本的內容是否有變化。在腳本末尾可以叫上獲得真實的路徑緩存使用大小。 php.ini文件 有這么一個工具,可以檢查ini文件是否使用了安全方面的最佳實踐 composer require psecio/iniscan htps...
閱讀 1316·2021-09-27 13:56
閱讀 2347·2019-08-26 10:35
閱讀 3510·2019-08-23 15:53
閱讀 1857·2019-08-23 14:42
閱讀 1240·2019-08-23 14:33
閱讀 3572·2019-08-23 12:36
閱讀 1955·2019-08-22 18:46
閱讀 1006·2019-08-22 14:06