2012-04-05 7 views
5

According to the documentation:reale max_execution_time per PHP su Linux

max_execution_time only affect the execution time of the script itself. 
Any time spent on activity that happens outside the execution of the script 
such as system calls using system(), stream operations, database queries, etc. 
is not included when determining the maximum time that the script has been running. 
This is not true on Windows where the measured time is real. 

Ciò è confermato da test:

non saranno sospese

<?php 
set_time_limit(5); 
$sql = mysqli_connect('localhost','root','root','mysql'); 
$query = "SELECT SLEEP(10) FROM mysql.user;"; 
$sql->query($query) or die($query.'<br />'.$sql->error); 
echo "You got the page"; 

scadrà

<?php 
set_time_limit(5); 
while (true) { 
    // do nothing 
} 
echo "You got the page"; 

Il nostro problema è che ci piacerebbe molto che PHP scadesse, indipendentemente da ciò che sta facendo, dopo un certo periodo di tempo (dato che non vogliamo mantenere le risorse impegnate se sappiamo di aver fallito nel consegnare una pagina in un tempo accettabile, come 10 secondi). Sappiamo che possiamo giocare con impostazioni come lo MySQL wait_timeout per le query SQL, ma il timeout della pagina dipenderà dal numero di query che vengono eseguite.

Alcune persone hanno provato a trovare workarounds e non sembra implementabile.

D: C'è un modo semplice per ottenere un vero PHP max_execution_time su linux, o siamo una migliore tempistica altrove, come ad esempio Apache livello?

risposta

5

Questo è piuttosto un consiglio difficile, ma sarà sicuramente fare cosa vuoi, se sei disposto a modificare e ricompilare PHP.

Dai un'occhiata al codice sorgente PHP https://github.com/php/php-src/blob/master/Zend/zend_execute_API.c (il file è Zend/zend_execute_API.c), alla funzione zend_set_timeout. Questa è la funzione che implementa il limite di tempo. Ecco come funziona su diverse piattaforme:

  • su Windows, creare un nuovo thread, avviare un timer su di esso, e quando finisce, impostare una variabile globale chiamata timed_out a 1, l'esecuzione di PHP controlli fondamentali di questa variabile per ogni istruzione, poi esce (molto semplificato)

  • su Cygwin, utilizzare itimer con ITIMER_REAL, che misura reale tempo, tra cui il sonno, l'ora, qualunque sia, quindi sollevare un segnale che interromperà qualsiasi elaborazione e interruzione dell'elaborazione

  • su altri sistemi unix, utilizzare itimer con ITIMER_PROF, che misura solo il tempo di CPU impiegato dal processo corrente (ma sia in modalità utente che in modalità kernel). Ciò significa che attendere altri processi (come MySQL) non conta in questo.

Ora ciò che si vuole fare è quello di cambiare l'itimer sul vostro Linux da ITIMER_PROF a ITIMER_REAL, che naturalmente è necessario fare manualmente, ricompilare, installare etc.L'altra differenza tra questi due è che usano anche un segnale diverso quando il timer si esaurisce. Quindi il mio suggerimento è quello di cambiare l'ifdef:

# ifdef __CYGWIN__ 

in

# if 1 

in modo che si imposta sia ITIMER_REAL e il segnale che PHP attende a SIGALRM.

Comunque tutta questa idea non è testato (Io lo uso per qualche sistema molto specifico, dove ITIMER_PROF è rotto, ed è sembra al lavoro), non supportato, ecc Usatelo a vostro rischio. Può funzionare con PHP stesso, ma potrebbe rompere altri moduli, in PHP e in Apache, se per qualsiasi motivo, utilizzare il segnale SIGALRM o un altro timer.

-2

Da httpd.conf:

Timeout: Il numero di secondi prima che riceve e invia time out

Timeout 300

+1

questo non influirà sull'elaborazione PHP – kuba

+0

infatti, ho testato con 'TimeOut' di Apache impostato su' 2' (secondi) e non ha alcun effetto. C'è qualcos'altro oltre a 'mod_reqtimeout' puoi consigliare John? – Max

1

Questa è una domanda vecchia e risposta. Ma per il bene di aiutare gli altri, ho voluto sottolineare l'opzione php-fpm request_terminate_timeout. Se stai usando PHP-FPM, è molto probabilmente quello di cui hai bisogno.

Se impostato, questa opzione consente di indicare a PHP-FPM di terminare una richiesta dopo N secondi, indipendentemente da ciò che fa PHP.

Vedere http://php.net/manual/en/install.fpm.configuration.php#request-terminate-timeout per dettagli.

Problemi correlati