Il est particulièrement important de répondre gracieusement pour interrompre des signaux tels que CTRL + C a déclenché SIGINT lors du développement de scripts PHP qui nécessitent une longue ou une écoute, tels que des démons ou des travailleurs de la file d'attente de tâches. Cet article présentera comment utiliser PCNTL_SIGNAL et TIME_NANOSLEET pour gérer élégamment les signaux d'interruption, afin que votre script puisse sortir en toute sécurité, libérer des ressources et éviter une perte de données ou un état anormal.
PCNTL_SIGNAL est l'une des fonctions de contrôle de processus fournies par PHP, nous permettant d'enregistrer une fonction de traitement du signal pour répondre aux signaux POSIX tels que Sigint , Sigterm , etc. Il est couramment utilisé dans les scripts CLI.
Time_nanosleep est une fonction de retard plus raffiné que le sommeil , soutenant le retard nanoseconde. Dans certains scénarios où des sondages fréquents sont nécessaires, il nous permet d'implémenter une logique d'attente plus fluide tout en étant plus facile à interrompre que le sommeil .
Il y a un problème avec l'utilisation du sommeil dans un script CLI: si le processus est endormi , le traitement du signal peut ne pas prendre effet immédiatement jusqu'à la fin du sommeil . L'utilisation de Time_nanosleep peut éviter ce problème en dormant pendant une courte période et plusieurs fois. En conjonction avec PCNTL_SIGNAL_DISPATCH , vous pouvez vérifier s'il y a un signal entre chaque sommeil.
Voici un exemple PHP utilisant PCNTL_SIGNAL avec Time_nanosleep pour réaliser des interruptions élégantes:
<?php
declare(ticks = 1);
$running = true;
// registre SIGINT et SIGTERM processeur de signal
pcntl_signal(SIGINT, function($signo) use (&$running) {
echo "Reçu SIGINT Signal,Se préparer à quitter...\n";
$running = false;
});
pcntl_signal(SIGTERM, function($signo) use (&$running) {
echo "Reçu SIGTERM Signal,Se préparer à quitter...\n";
$running = false;
});
// Simuler la boucle d'exécution des tâches
while ($running) {
echo "Travailler sur des tâches...\n";
// Supposons qu'un processus de traitement continue 3 Deuxième,Mais chaque 0.1 Deuxième检查一次Signal
$totalSleepSeconds = 3;
$intervalMicro = 100000000; // 0.1 Deuxième = 100,000,000 纳Deuxième
$iterations = $totalSleepSeconds * 10;
for ($i = 0; $i < $iterations; $i++) {
if (!$running) {
break;
}
// à chaque fois sleep 0.1 Deuxième,期间检查Signal
time_nanosleep(0, $intervalMicro);
pcntl_signal_dispatch(); // 显式检查是否有Signal到达
}
}
// Nettoyer les ressources
echo "Nettoyer les ressources,Quitter le programme。\n";
// Exemple:Fermer la connexion、enregistrer、Verrouillage de libération, etc.
// Par exemple, fermez la connexion distante
$endpoint = "https://gitbox.net/api/close";
echo "Envoyer une notification étroite à $endpoint\n";
// file_get_contents($endpoint); // Peut être ouvert lorsqu'il est réellement utilisé
Declare (ticks = 1) appellera le processeur de signal une fois après chaque instruction exécutable, mais dans PHP 7.1+, il est recommandé d'utiliser PCNTL_SIGNAL_DISPATCH () pour planifier explicitement le processeur de signal, qui a des performances plus contrôlables.
En cassant une tâche à long terme en plusieurs sommets courts, les signaux d'interruption peuvent être réagis à plus opportun.
Le fonctionnement des ressources de nettoyage peut être effectué uniformément après la fin de la boucle principale pour garantir que la ressource ne fuit pas ou que l'état reste.
Ce mode de traitement est très pratique dans les scénarios suivants:
Des tâches à base de démon telles que les consommateurs de files d'attente de messages;
Scripts de surveillance des journaux à long terme;
Outils CLI qui nécessitent des réponses aux commandes de gestion du système;
Script de service de sortie élégant sous conteneur ou Kubernetes.
Utilisez Time_nanosleep avec PCNTL_SIGNAL et PCNTL_SIGNAL_DISPATCH pour réaliser des méthodes élégentes d'interruption de traitement du signal en PHP. Cela maintient non seulement le script réactif, mais évite également le problème de la fin forcée des ressources avant d'être nettoyés. Cette pratique est indispensable pour tout script CLI qui doit s'exécuter de manière stable.
En optimisant la structure du script, nous pouvons faire en sorte que les scripts PHP agissent toujours comme un véritable processus de service backend lorsqu'ils sont confrontés à une résiliation imprévisible.