PHP utilise pcntl et libevent pour implémenter la fonction Timer. Regardons d'abord l'exemple pcntl (thread PHP) expliqué ci-dessous.
<?php function newChild($func_name) { echo "enter newChild\n"; $args = func_get_args(); unset($args[0]); $pid = pcntl_fork(); if ($pid == 0) { function_exists($func_name) and exit(call_user_func_array($func_name, $args)) or exit(-1); } else if($pid == -1) { echo "Couldn't create child process"; } else { return $pid; } } (PS:^_^不错的php开发交流群:256271784,验证:csl,有兴趣的话可以加入进来一起讨论) function on_timer() { echo "timer called\n"; } /** * @param $func string, function name * @param $timeouts int, microtimes for time delay */ function timer($func, $timeouts){ echo "enter timer\n"; $base = event_base_new(); $event = event_new(); event_set($event, 0, EV_TIMEOUT, $func); event_base_set($event, $base); event_add($event, $timeouts); event_base_loop($base); } $pid = newChild("timer", "on_timer", 5000000); if ($pid > 0) { echo "master process exit\n"; }
PHP étend pcntl pour implémenter le "multi-threading" (processus)
pcntl et ticks
les ticks sont définis via la syntaxe declare(ticks = n) {statement} La syntaxe de déclaration ne peut actuellement accepter que. ticks. La signification de ticks = n qu'il a défini est que lorsque N instructions de bas niveau sont exécutées dans le bloc d'instructions spécifié par declare, cet événement peut être enregistré via register_tick_function($function_name).
Le mécanisme de signal. de pcntl est basé sur le mécanisme ticks implémenté. Par conséquent, lorsque nous utilisons des fonctions liées au signal dans la famille de fonctions pcntl, nous devons ajouter la structure syntaxique declare(ticks = n) devant.
int pcntl_alarm(int $ secondes):
$secondes secondes processus en arrière Envoyez un signal SIGALRM, et chaque appel à la méthode pcntl_alarm annulera l'horloge précédemment définie.
void pcntl_exec(string $path[, array $args[, array $env] ]):
Exécuter un programme dans l'espace de processus actuel.
$path : doit être un fichier exécutable binaire ou un chemin de fichier de script avec des informations d'en-tête de script valides (#!/usr/local/bin/php) .
$args : Caractères à passer au programme Liste des paramètres String (forme tableau)
$envs : variable d'environnement. Passer à la variable d'environnement du programme à exécuter sous forme de tableau (clé => formulaire de valeur).
int pcntl_for k (void):
Créer un processus enfant, qui est différent du processus parent uniquement en PID (numéro de processus) et PPID (numéro de processus parent
Renvoie le créé). pid du processus enfant lorsque le thread parent s'exécute et renvoie 0 lorsque le thread enfant s'exécute. Créer Lorsque le processus enfant échoue, -1 sera renvoyé dans le contexte du processus parent et une erreur php sera déclenchée
Pour comprendre le fork. ici, vous devez savoir : pcntl_fork crée un nœud de branche, ce qui équivaut à une marque. Une fois le processus parent terminé, le processus enfant démarrera à partir de l'exécution se poursuit à la marque, ce qui signifie que le code après pcntl_fork est exécuté deux fois par le processus parent et le processus enfant respectivement, et les valeurs de retour obtenues par les deux processus lors de l'exécution sont différentes, par conséquent, les processus parent et enfant peuvent être séparés pour exécuter des codes différents .
int pcntl_getpriority([int $. pid = getmypid()[, int $process_identifier = PRIO_PROCESS]]) :
Obtenir la priorité du processus correspondant au $pid donné La valeur par défaut est obtenue via getmypid() La valeur est le processus actuel. $pid : S'il n'est pas spécifié, la valeur par défaut est le processus actuel.
$process_identifier : L'un des PRIO_PGRP, PRIO_USER, PRIO_PROCESS, la valeur par défaut est PRIO_PROCESS Parmi eux, PRIO_PGRP fait référence à la priorité d'obtention du groupe de processus, PRIO_USER fait référence à. obtenir la priorité du processus utilisateur, PRIO_PROCESS fait référence à l'obtention de la priorité d'un processus spécifique.
Renvoie la priorité du processus, ou renvoie false lorsqu'une erreur se produit. Plus la valeur est petite, plus la priorité est élevée
bool. pcntl_setpriority(int $priority[ , int $pid = getmypid()[, int $process_identifier = PRIO_PROCESS]] :
Définissez la priorité du processus.
$priority : valeur de priorité, comprise entre -20 et 20, la priorité par défaut est 0 . Plus la valeur est petite, plus la priorité est élevée
$pid : S'il n'est pas spécifié, il fait référence au processus actuel
$process_identifier : La signification est la même que celle de pcntl_getpriority. .
Renvoie TRUE si le réglage réussit, et FALSE s'il échoue
bool pcntl_signal_dispatch(void):
Appelez le gestionnaire du signal à venir installé via pcntl_signal().
L'appel renvoie TRUE. en cas de succès, false en cas d'échec.
php 5.3.3 ajouté
bool pcntl_signal(int $signo, callback $handler[, bool $restart_syscalls = true]):
Installer un nouveau gestionnaire de signal $handler pour le signal spécifié $signo.
Le dernier paramètre n'a aucune signification.
bool pcntl_sigprocmask (int $how, array $set[, array &$oldset]) :
Ajouter, supprimer ou définir le signal de verrouillage, le le comportement spécifique dépend du paramètre $how
$how : SIG_BLOCK est utilisé pour ajouter le signal au signal de verrouillage actuel. Parmi les signaux de verrouillage actuels, SIG_UNBLOCK est utilisé pour supprimer le signal du signal de verrouillage actuel et SIG_SETMASK est utilisé pour remplacer le verrouillage actuel. signal avec la liste de signaux donnée.
$set : La liste des signaux à ajouter, supprimer ou définir.
$oldset : utilisé pour renvoyer l'ancien signal de verrouillage à l'appelant.
Renvoie TRUE en cas de succès, FAUX en cas d'échec.
int pcntl_sigtimedwait(array $set[, array &$siginfo[, int $seconds = 0[, int $nanoseconds = 0]]]):
pcntl_sigtimedwait fait en fait la même chose que pcntl_sigwaitinfo( ), mais pcntl_sigtimedwait a deux paramètres améliorés supplémentaires $seconds et $nanoseconds, ce qui permet au script de rester plus longtemps. Il y a une limite supérieure au lieu d'une attente illimitée
$set : liste des signaux qui doivent être attendus
. $siginfo : Utilisé pour renvoyer des informations à l'appelant sur les signaux à attendre. Pour le contenu des informations, voir pcntl_sigwaitinfo
$seconds : Timeout Le nombre de secondes
$nanoseconds : Le nombre de nanosecondes pour le timeout
. Après succès, pcntl_sigtimedwiat() renvoie le numéro de signal
int pcntl_sigwaitinfo(array $set[, array &$siginfo]) :
Pending current Le script est exécuté jusqu'à ce qu'un signal dans $set soit reçu si l'un des. les signaux sont sur le point d'arriver (comme être verrouillé par pcntl_sigprocmask), alors pcntl_sigwaitinfo retournera immédiatement
$set : liste des signaux en attente
$siginfo : Utilisé pour renvoyer à l'appelant les informations du signal en attente du signal, qui contient le contenu suivant :
1. Tous les signaux ont les trois informations suivantes :
a) signo : numéro de signal
b) errno : numéro d'erreur
c) code : code du signal
2. Informations spécifiques au signal SIGCHLD
a) statut : valeur ou signal de sortie
b) utime : temps de consommation de l'utilisateur
c) stime : temps de consommation du système
d) pid : identifiant du processus d'envoi
e) uid : identifiant utilisateur réel du processus d'envoi
3 Informations appartenant à SIGILL, SIGFPE, SIGSEGV, SIGBUS
a) addr : emplacement mémoire où le défaut s'est produit4. Informations uniques SIGPOLL :
a) band : événement de bande, signifiant inconnu
b) fd : descripteur de fichier
La fonction s'exécute avec succès et renvoie le numéro de signal
int pcntl_wait(int &$status [ , int *options = 0]):
Suspendez le processus en cours jusqu'à ce qu'un processus enfant se termine ou jusqu'à ce qu'un signal demande la fin du processus en cours ou qu'une fonction de gestion du signal soit appelée si le processus enfant s'est déjà terminé lorsqu'il est appelé. (communément appelé processus zombie), cette fonction reviendra immédiatement et toutes les ressources système seront libérées
$status est utilisé pour enregistrer les informations d'état du processus enfant, qui sont générées par les fonctions suivantes : pcntl_wifexited, pcntl_wifstopped, pcntl_wifsignaled, pcntl_wexitstatus, pcntl_wtermsig, pcntl_wstopsig .
$options : si votre système autorise wait3 (la plupart des systèmes de type BSD), vous pouvez fournir un paramètre d'options facultatif. Si ce paramètre n'est pas fourni, wait utilisera l'appel système. . Si le système n'autorise pas wait3 , à condition que ce paramètre n'ait aucun effet, la valeur de $options peut être 0 ou les deux constantes WNOHANG et WUNTRACED
La fonction renvoie le PID du processus enfant sortant, ou -1 sur. erreur, ou si WNOHANG est fourni en option (wait3 système indisponible) et qu'il n'y a pas de processus enfant valide, renvoie 0
Processus zombie : étant donné que le processus parent est après fork, il est impossible de prédire quand le processus enfant se terminera, donc Afin de laisser certaines informations au processus parent, le processus enfant quittera. La structure de données suivante appelée zombie attend une opération d'attente initiée par le processus parent pour récupérer son cadavre. Le processus enfant est appelé processus zombie pendant la période intermédiaire. la fin du processus enfant (fin logique) et la récupération de son cadavre par le processus parent. Après la fin, tous les processus enfants seront remis à Init. Par conséquent, si le processus parent se termine, les processus zombies seront recyclés. Cependant, si le processus parent ne se termine jamais, ces processus zombies occuperont toujours le numéro de processus. Si le numéro de processus système est épuisé, cela entraînera l'impossibilité de démarrer un nouveau processus. Par conséquent, la méthode la plus sûre est. pour collecter les cadavres des processus enfants générés par lui-même dans le processus parent.
int pcntl_waitpid(int $pid, int &$status[, int $options = 0 ]):
Suspendez le processus en cours jusqu'à ce que l'enfant le processus avec le $pid donné se termine, ou le processus actuel reçoit un signal de sortie, ou reçoit un signal ige pour appeler un gestionnaire de signal.
Si $pid est donné, le processus enfant correspondant s'est terminé (état zombie) lors de l'appel de cette fonction , la fonction est renvoyée immédiatement et toutes les ressources système sont libérées.
$pid : le numéro de processus, inférieur à -1 indique qu'il attend tout processus enfant dans le groupe de processus, le numéro de groupe de processus est la valeur absolue de $. pid. Égal à -1 signifie attendre n'importe quelle Cité interdite, cohérent avec le comportement de la fonction pcntl_wait. Égal à 0 signifie attendre un processus enfant dans le même groupe que le processus appelant, et supérieur à 0 signifie qu'il s'agit d'un processus spécifique. .
$status : utilisé pour renvoyer l'état du processus enfant à partir de la fonction. Ces informations d'état sont générées par les fonctions suivantes : pcntl_wifstopped, pcntl_wifsignaled, pcntl_wexitstatus, pcntl_wtermsig, pcntl_wstopsig.
$options : a la même signification. comme $options
int pcntl_wexitstat us (int $status) de pcntl_wait :
Renvoie le code de retour d'un processus enfant interrompu. Cette fonction n'est utile que lorsque la fonction pcntl_wifexited renvoie TRUE.
Le paramètre $status est l'information d'état. généré par pcntl_waitpid.
bool pcntl_wifexited(int $status):
Vérifiez si l'état donné indique que le processus enfant s'est terminé normalement.
bool pcntl_wifsignaled(int $status):
Vérifiez si l'état donné indique que le processus enfant s'est arrêté suite à la réception d'un certain signal.
bool pcntl_wifstopped(int $status):
Vérifiez si $status peut indiquer que le processus enfant est actuellement arrêté. Cette fonction génère uniquement $status lorsqu'elle agit. WUNTRACED utilisé par la fonction pcntl_waitpid comme valeur du paramètre $options. Il n'est valable que ci-dessus.
int pcntl_wstopsig(int $status) :
Renvoie le numéro du signal qui arrête le processus enfant en analysant $status. . Cette fonction n'est valide que lorsque pcntl_wifsignaled renvoie VRAI.
int pcntl_wtermsig(int $status):
Renvoie le numéro du signal qui interrompt le processus.