PHP の set_time_out および max_execution_time 設定

不言
リリース: 2023-03-22 17:40:02
オリジナル
2998 人が閲覧しました

この記事では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 です (つまり、ユーザー モードとカーネル モードで消費されるリアルタイムのみを計算します)
ただし、スリープは一定期間プロセスを一時停止します。操作は実行されません。時間は消費されないため、このスリープではカーネル時間もユーザー時間も消費されません。
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")
説明
システムは、各プロセスに 3 つのインターバル タイマーを提供し、それぞれが個別の時間領域で減少します。タイマーが期限切れになると、シグナルがプロセスに送信され、タイマーが (場合によっては) 再起動されます。

ITIMER_REAL

はリアルタイムでデクリメントし、期限切れ時にSIGALRMを配信します。

ITIMER_VIRTUAL
はプロセスの実行時のみデクリメントし、期限切れ時にSIGVTALRMを配信します。

ITIMER_PROF

は、プロセスの実行時とシステムの実行時の両方でデクリメントします。プロセスに代わって実行されます。ITIMER_VIRTUAL と組み合わせて、このタイマーは通常、ユーザーおよびカーネル空間でアプリケーションが費やした時間をプロファイルするために使用されます。


ITIMER_PROF オプションで実行されるプロセスを確認してください。 PHPプロセスの実行ではないでしょうか?プロセスの実行には問題ありませんが、スリープ機能によりプロセスが一時停止されるため、スリープ中の内容はカウントされません。そのため、ユーザーモードでの実行時間は睡眠後以外はずっとかかります

🎜具体的に違いがあるとしたら、ソースコードにはどのように反映されるのでしょうか?もう一度追いかけます🎜🎜 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 の下で、🎜rrreeeがあります🎜 次に、zendディレクトリでzend_set_timeoutを検索し、zend_execute_api.cでITIMER_PROFを見つけます🎜🎜🎜🎜🎜🎜🎜🎜それが彼です! 🎜🎜🎜🎜

以上がPHP の set_time_out および max_execution_time 設定の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート