Di seguito sono i miei risultati, non posso fornire alcun riferimento alla documentazione per dimostrare le mie affermazioni. Tuttavia, ho imparato il modo in cui l'interprete PHP gestisce i tick e i segnali leggendo il codice sorgente del PHP (lo pcntl
extension).
- Se impostiamo
ticks = 5
, significa che abbiamo un 4 a 5 caso il gestore di segnale non sarà chiamato a tutti?
PHP è un linguaggio interpretato. I gestori di segnale PHP non vengono richiamati dal sistema operativo per gestire i segnali. L'interprete registra un gestore di segnale con il sistema operativo e mette tutti i segnali che riceve in una coda.
I segnali del sistema operativo sono asincroni. L'interprete invia i segnali ai gestori definiti da te quando è il momento più appropriato per farlo. Questo accade tra le affermazioni di basso livello
declare(ticks = 5);
fa funzionare il dispatcher di segnali una volta ogni 5 dichiarazioni tickable. I segnali che arrivano durante due chiamate al dispatcher non vengono persi; vengono aggiunti alla coda ed elaborati alla prossima chiamata.
Il codice del dispatcher di segnali è piuttosto leggero; non è un grande overhead usare declare(ticks = 1)
.
- Come posso determinare un ambiente coerente ma efficiente?
Dipende da cosa fa il programma. Non c'è una ricetta per questo. Prova diverse impostazioni, scegli quello che ti si addice meglio.
- ciò che accade durante il blocco delle chiamate, come le query di database? Il segnale viene gettato via o elaborato quando ritorna?
Come detto sopra, i segnali provengono e vengono elaborati in modo asincrono dal gestore di segnale installato dall'interprete. La gestione mette solo i segnali in coda. Vengono scelti dalla coda e inviati al tuo codice quando è il momento più appropriato per l'interprete (e anche il tuo codice PHP). Niente è perso.
Per quanto riguarda il database, ho controllato solo (alcuni anni fa) con mysql
. Il mio codice utilizzava pcntl_fork()
per creare processi di lavoro e stava elaborando SIGCHLD
per tenere traccia dell'attività dei lavoratori. Per ragioni misteriose, le query MySQL non funzionavano spesso con il messaggio "connessione persa" senza alcuna ragione apparente. Dopo un'approfondita ricerca e lettura di molta documentazione, ho scoperto che i segnali fanno in modo che le funzioni della famiglia sleep()
vengano restituite anticipatamente e che il codice della libreria client mysql
ritenga che la connessione sia stata persa.
La soluzione era molto semplice. Ho utilizzato pcntl_sigprocmask()
per bloccare il segnale SIGCHLD
prima di eseguire una query MySQL e sbloccarlo immediatamente al termine della query. Non ero interessato ad altri segnali. Lasciarli venire porterebbe alla fine del processo; perché preoccuparsi di una query MySQL fallita quando il programma stava per uscire comunque?
Non so se i segnali influenzano il funzionamento di mysqli
o PDO
ma penso che lo facciano. L'operazione che era interessata nel mio caso era parte della comunicazione di basso livello tra il client e il server MySQL, in profondità nello libmysql
e non nell'estensione PHP.
Nel tuo caso, probabilmente devi bloccare SIGHUP
(questo è il segnale che di solito viene inviato ai daemon per farli ricaricare la loro configurazione).
Vorrei che la documentazione di PHP fosse così completa! Grazie mille, questo è esattamente quello che volevo sapere. –