To dość trudna rada, ale na pewno zrobi to, co chcesz, jeśli chcesz modyfikować i rekompilować PHP.
Spójrz na kod źródłowy PHP pod adresem https:// github.com/php/php-src/blob/master/Zend/zend_execute_API.c
(plik to Zend/zend_execute_API.c
), w funkcji zend_set_timeout
. Jest to funkcja realizująca limit czasu. Oto jak to działa na różnych platformach:
-
w systemie Windows utwórz nowy wątek, uruchom na nim licznik czasu, a kiedy skończy, ustaw zmienną globalną o nazwie
timed_out
na 1, jądro wykonawcze PHP sprawdza tę zmienną dla każdej instrukcji, a następnie kończy działanie (bardzo uproszczone) -
na Cygwinie użyj itimera z ITIMER_REAL, który mierzy rzeczywistość czas, w tym sen, poczekaj, cokolwiek, a następnie podnieś sygnał który przerwie dowolne przetwarzanie i zatrzymanie przetwarzania
-
w innych systemach uniksowych użyj itimera z ITIMER_PROF, który mierzy tylko czas procesora spędzony przez bieżący proces (ale zarówno w trybie użytkownika, jak i trybie jądra). Oznacza to, że nie liczy się czekanie na inne procesy (takie jak MySQL).
Teraz to, co chcesz zrobić, to zmienić itimer w systemie Linux z ITIMER_PROF na ITIMER_REAL, co oczywiście musisz zrobić ręcznie, przekompilować, zainstalować itp. Inną różnicą między tymi dwoma jest to, że używają również innego sygnału, gdy działa licznik czasu na zewnątrz. Więc moja sugestia to zmiana ifdef:
# ifdef __CYGWIN__
do
# if 1
aby ustawić zarówno ITIMER_REAL, jak i sygnał, na który PHP czeka na SIGALRM.
W każdym razie cały ten pomysł nie został przetestowany (używam go w bardzo specyficznym systemie, w którym ITIMER_PROF jest zepsuty i wydaje się do pracy), nieobsługiwane itp. Używaj go na własne ryzyko. Może działać z samym PHP, ale może zepsuć inne moduły, w PHP i w Apache, jeśli z jakiegoś powodu używają sygnału SIGALRM lub innego timera.