>  기사  >  백엔드 개발  >  PHP의 set_time_out 및 max_execution_time 설정

PHP의 set_time_out 및 max_execution_time 설정

不言
不言원래의
2018-04-26 14:27:532988검색

이 글에서는 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);
}

이런 줄 알았는데, cli에서의 결과는

012345678910

입니다. fpm도 마찬가지입니다.

생각하는 방법

먼저 매뉴얼 함수를 읽으면 요약은 다음과 같습니다.

set_time_limit() 함수 및 구성 명령 max_execution_time은 스크립트 자체의 실행 시간에만 영향을 줍니다. 스크립트가 이미 실행 중인 상태에서 system()을 사용한 시스템 호출, 스트림 작업, 데이터베이스 작업 등 발생하는 스크립트 실행에는 최대 스크립트 실행 시간이 포함되지 않습니다. 측정된 시간이 실제 값을 갖는 Windows에서는 그렇지 않습니다.

아직도 혼란스럽습니다.
또 다른 문장도 봤습니다:

PHP가 안전 모드에서 실행 중이면 이 기능이 적용되지 않습니다. 안전모드를 끄거나 php.ini에서 시간제한을 변경하는 것 외에는 방법이 없습니다

특별히 살펴보니 안전모드가 아니었습니다. .

그러다가 의아해했고 관계자로부터 참을성 있는 답변을 받았습니다.

php zend 엔진은 settimer를 사용하여 max_execute_time을 구현하고 매개변수는 ITIMER_PROF입니다(즉, 사용자 모드와 커널 모드에서 소비되는 실제 시간만 계산합니다)
하지만 sleep은 일정 시간 동안 프로세스를 일시 중지하고, 작업이 수행되지 않으므로 시간 소모가 없으므로 이 절전 모드는 커널 시간이나 사용자 시간을 소모하지 않습니다.
C 프로그램을 작성해서 검증해봤습니다. 실제로 슬립 상태에서는 시간 통계가 전혀 없고, 시그널 핸들러도 실행되지 않습니다..

그러면 이 [ITIMER_PRO][3]를 추적하겠습니다. ]F 매개변수[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 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")
Description
시스템은 각 프로세스에 3개의 간격 타이머를 제공하며, 각 타이머는 고유한 시간 영역에서 감소하며, 신호가 프로세스에 전송되고 타이머가 (잠재적으로) 다시 시작됩니다.

ITIMER_REAL

은 실시간으로 감소하고 만료 시 SIGALRM을 제공합니다.

ITIMER_VIRTUAL
은 프로세스가 실행 중일 때만 감소하고 만료 시 SIGVTALRM을 제공합니다.

ITIMER_PROF

프로세스가 실행될 때와 시스템이 실행될 때 모두 감소합니다. ITIMER_VIRTUAL과 함께 이 타이머는 일반적으로 사용자 및 커널 공간에서 애플리케이션이 소비한 시간을 프로파일링하는 데 사용됩니다. SIGPROF는 만료 시 전달됩니다.


ITIMER_PROF 옵션에서 실행되는 프로세스를 살펴보세요. PHP 프로세스 실행이 아닌가요? 프로세스 실행에는 문제가 없으나, sleep 기능으로 인해 프로세스가 일시 중단되므로 sleep 상태의 내용은 카운트되지 않습니다. 따라서 유저모드에서의 실행시간은 잠든 시간을 제외하고는 항상 입니다

🎜구체적인 차이점이 있다면 소스코드에는 어떻게 반영되나요? 다시 추적🎜🎜다음에 main.c를 다운로드🎜
        }        if (PG(max_input_time) != -1) {#ifdef PHP_WIN32
            zend_unset_timeout();#endif
            zend_set_timeout(INI_INT("max_execution_time"), 0);
        }
🎜키 라인 sizeof("max_execution_time")을 살펴봅시다🎜그 다음 max_execution_time을 추적🎜또는 다시 main.c 아래에 있습니다. c, 🎜rrreee🎜가 있습니다. 그런 다음 zend 디렉터리에서 zend_set_timeout을 검색하고 zend_execute_api.c🎜🎜🎜🎜🎜🎜🎜🎜에서 ITIMER_PROF를 찾으세요. 바로 그 사람입니다! 🎜🎜🎜🎜

위 내용은 PHP의 set_time_out 및 max_execution_time 설정의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.