Maison  >  Article  >  développement back-end  >  Paramètres set_time_out et max_execution_time de PHP

Paramètres set_time_out et max_execution_time de PHP

不言
不言original
2018-04-26 14:27:533000parcourir

Cet article vous présente les paramètres set_time_out et max_execution_time de PHP. Les amis dans le besoin peuvent s'y référer.


Intention


Je veux qu'un script php (sous fpm ou cli) n'en exécute que 5 via set_time_out ou max_execution_time paramètres Deuxièmement.

Au départ, je pensais que le code était comme ça

<?phpini_set("max_execution_time",5);
set_time_limit(5);for($i=0;$i<=10;$i++)
{echo $i."\n";
sleep(1);
}

Mais le résultat sous cli est

012345678910

Il en va de même pour fpm.

Thinking Way

Lisez d'abord la fonction manuelle, le résumé est le suivant :

La fonction set_time_limit() et l'instruction de configuration max_execution_time n'affectent que le temps d'exécution du script lui-même. La durée maximale d'exécution du script n'est pas incluse dans toute exécution de script qui se produit, comme les appels système utilisant system(), les opérations de flux, les opérations de base de données, etc., lorsque le script est déjà en cours d'exécution. Sous Windows, où les temps mesurés sont des valeurs réelles, ce n'est pas le cas.

Toujours confus.
J'ai également vu une autre phrase :

Lorsque php s'exécute en mode sans échec, cette fonction ne peut pas prendre effet. Il n'y a pas d'autre moyen que de désactiver le mode sans échec ou de changer la limite de temps dans php.ini

J'ai jeté un coup d'œil particulier et ce n'était pas le mode sans échec. .

Ensuite, j'ai été perplexe et j'ai reçu une réponse patiente du fonctionnaire.

Le moteur php zend implémente max_execute_time à l'aide d'un settimer, et le paramètre est ITIMER_PROF (ce qui signifie que cela ne calcule que le temps réel consommé par le mode utilisateur et le mode noyau)
Mais le mode veille suspend le processus pendant une période de time. Aucune opération n'est effectuée et aucun temps n'est consommé, donc cette veille ne consomme ni le temps du mode noyau ni le temps du mode utilisateur.
J'ai écrit un programme C pour le vérifier. En effet, en état de veille, il n'y a aucune statistique de temps et le gestionnaire de signal ne sera pas déclenché..

Ensuite, je vais poursuivre cela paramètre[ITIMER_PRO][3]F

Description
Le système fournit à chaque processus trois minuteurs d'intervalle, chacun décrémentant dans un domaine temporel distinct. Lorsqu'un minuteur expire, un signal est envoyé au processus et le minuteur redémarre (potentiellement). .
ITIMER_REAL

décrémente en temps réel et délivre SIGALRM à l'expiration.

ITIMER_VIRTUAL

décrémente uniquement lorsque le processus est en cours d'exécution et délivre SIGVTALRM à l'expiration. 🎜>

décrémente à la fois lorsque le processus s'exécute et lorsque le système s'exécute au nom du processus. Couplé à ITIMER_VIRTUAL, ce minuteur est généralement utilisé pour profiler le temps passé par l'application dans l'espace utilisateur et le noyau. expiration.

Regardez le processus qui s'exécute dans l'option ITIMER_PROF. N'est-ce pas l'exécution du processus php ? Il n'y a aucun problème avec l'exécution du processus, mais la fonction sleep suspendra le processus, donc le contenu en veille n'est pas compté. Par conséquent, le temps d'exécution en mode utilisateur est tout le temps sauf après votre sommeil

S'il y a une différence spécifique, comment se reflète-t-elle dans le code source ? Poursuivez à nouveau

et

jusqu'au suivant

Regardons la ligne clé main.c

puis poursuivons max_execution_time
/* {{{ 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);
}
ou allons à main.c Suivant , il y a

sizeof("max_execution_time")
, puis recherchez zend_set_timeout dans le répertoire zend, puis trouvez ITIMER_PROF

        }        if (PG(max_input_time) != -1) {#ifdef PHP_WIN32
            zend_unset_timeout();#endif
            zend_set_timeout(INI_INT("max_execution_time"), 0);
        }

C'est lui !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn