Comment PHP gère les signaux de processus (avec exemples)

不言
Libérer: 2023-04-04 08:26:02
avant
2503 Les gens l'ont consulté

Le contenu de cet article explique comment PHP gère les signaux de processus (avec des exemples). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

php dispose d'un ensemble de fonctions de contrôle de processus PCNTL, qui permettent à php de créer des processus enfants, d'utiliser la fonction exec pour exécuter des programmes, de gérer des signaux et d'autres fonctions comme c dans les systèmes *nix.

Remarque : L'extension pcntl n'est disponible qu'en mode cli/cgi. Non disponible dans mod_php et php-fpm. N'utilisez pas cet ensemble de fonctions dans un environnement de serveur Web, car cela entraînerait des résultats imprévisibles. De plus, Windows, en tant que système non similaire à Unix, ne dispose pas de ces fonctions.

PCNTL utilise les ticks comme mécanisme de rappel de gestion du signal, ce qui peut minimiser la charge lors du traitement des événements asynchrones. Que sont les tiques ? Tick ​​​​est un événement qui se produit chaque fois que l'interpréteur exécute N instructions de bas niveau dans un segment de code. Ce segment de code doit être spécifié via declare.

Ce qui suit est un exemple d'envoi d'un signal SIGALRM toutes les 5 secondes, de l'obtenir par la fonction signal_handler, puis d'imprimer un "Caught SIGALRM" :

<?php   
        declare(ticks = 1);   
      
        function signal_handler($signal) {   
            print "Caught SIGALRM/n";   
            pcntl_alarm(5);   
        }   
      
        pcntl_signal(SIGALRM, "signal_handler", true);   
        pcntl_alarm(5);   
      
        while(true){

        }
      
    ?>
Copier après la connexion

En fait, les performances du signal pcntl_signal officiel est extrêmement médiocre.La raison principale est que les fonctions PHP ne peuvent pas être directement enregistrées dans les paramètres du signal du système d'exploitation, le signal pcntl doit donc s'appuyer sur le mécanisme de tick. Le principe d'implémentation de pcntl_signal est d'ajouter le signal à une file d'attente après avoir déclenché le signal. Vérifiez ensuite en permanence s'il y a un signal dans la fonction de rappel des ticks de PHP. S'il y a un signal, exécutez la fonction de rappel spécifiée dans PHP. Sinon, quittez la fonction. ticks=1 signifie que cette fonction sera rappelée à chaque fois qu'une ligne de code PHP est exécutée. En fait, aucun signal n'est généré la plupart du temps, mais la fonction ticks est toujours exécutée. Une meilleure approche consiste à supprimer les coches et à utiliser pcntl_signal_dispatch à la place pour gérer le signal vous-même dans la boucle de code.

Mise en place de pcntl_signal_dispatch

<?php
// 定义一个处理器,接收到SIGINT信号后只输出一行信息
function signalHandler($signo) {
    switch ($signo) {
        case SIGUSR1: echo "SIGUSR1\n"; break;
        case SIGUSR2: echo "SIGUSR2\n"; break;
        default:      echo "unknow";    break;
    }
}

//安装信号触发器器
pcntl_signal(SIGINT, &#39;signalHandler&#39;);
while (true) {
    sleep(1);
    posix_kill(posix_getpid(), SIGUSR1);///向当前进程发送SIGUSR1信号
    pcntl_signal_dispatch(); //接收到信号时,调用注册的signalHandler()
}
Copier après la connexion

Fonctions PCNTL :

Traitement du signal

int pcntl_alarm ( int $seconds )
Copier après la connexion

Définissez un compteur pour envoyer le signal SIGALRM après $secondes secondes

bool pcntl_signal(int $signo ,callback $handler [,bool $restart_syscalls=true])
Copier après la connexion

Définissez une fonction de rappel pour $signo pour gérer le signal

Le premier Le paramètre est le numéro du signal et le deuxième paramètre est la fonction PHP qui est rappelée lorsque le signal se produit. Le troisième paramètre est de savoir s'il faut redémarrer et s'il faut réenregistrer ce signal. Si ce paramètre est faux, alors ce signal n'est enregistré et traité qu'une seule fois.

Remarque : Chaque appel à pcntl_alarm() annulera le signal d'alarme et la fonction sleep() précédemment définis.

Ce qui suit est un exemple d'envoi d'un signal SIGALRM toutes les 5 secondes, de l'obtenir par la fonction signal_handler, puis d'imprimer un "Caught SIGALRM" :

<?php   
        declare(ticks = 1);   
      
        function signal_handler($signal) {   
            print "Caught SIGALRM/n";   
            pcntl_alarm(5);   
        }   
      
        pcntl_signal(SIGALRM, "signal_handler", true);   
        pcntl_alarm(5);   
      
        for(;;) {   
        }   
      
    ?>
Copier après la connexion

Exécuter le program

void pcntl_exec ( string $path [, array $args [, array $envs ]] )
Copier après la connexion

Exécuter le programme spécifié dans l'espace de processus actuel, similaire à la fonction de la famille exec dans c. L'espace dit actuel est l'espace où le code du programme spécifié est chargé et écrase le processus en cours. Le processus se termine après l'exécution du programme.

<?php   
    $dir = &#39;/home/test/&#39;;   
    $cmd = &#39;ls&#39;;   
    $option = &#39;-l&#39;;   
    $pathtobin = &#39;/bin/ls&#39;;   
      
    $arg = array($cmd, $option, $dir);   
      
    pcntl_exec($pathtobin, $arg);   
    echo &#39;123&#39;;    //不会执行到该行   
    ?>
Copier après la connexion

Créer un processus

int pcntl_fork ( void ) 为当前进程创建一个子进程
int pcntl_wait ( int &$status [, int $options ] ) 阻塞当前进程,只到当前进程的一个子进程退出或者收到一个结束当前进程的信号。 
int pcntl_waitpid ( int $pid , int &$status [, int $options ] ) 功能同pcntl_wait,区别为waitpid为等待指定pid的子进程。当pid为-1时pcntl_waitpid与pcntl_wait一样。
Copier après la connexion

Les informations d'état du processus enfant sont stockées dans $status dans les fonctions pcntl_wait et pcntl_waitpid. Ce paramètre peut être. utilisé pour les fonctions telles que pcntl_wifexited, pcntl_wifstopped, pcntl_wifsignaled, pcntl_wexitstatus, pcntl_wtermsig, pcntl_wstopsig et pcntl_waitpid.

Par exemple

<?php   
    $pid = pcntl_fork();   
    if($pid) { 
        pcntl_wait($status);   
        $id = getmypid();   
        echo "parent process,pid {$id}, child pid {$pid}/n";   
    } else {   
        $id = getmypid();   
        echo "child process,pid {$id}/n";   
        sleep(2);   
    }   
    ?>
Copier après la connexion

Le processus enfant dort pendant 2 secondes avant de se terminer après avoir généré des mots tels que processus enfant, tandis que le processus parent se bloque jusqu'à ce que le processus enfant se termine avant de continuer à s'exécuter.

Priorité du processus

int pcntl_getpriority ([ int $pid [, int $process_identifier ]] ) 取得进程的优先级,即nice值,默认为0。不同的系统类型以及内核版本下 优先级可能不同(手册中为-20到20)
bool pcntl_setpriority ( int $priority [, int $pid [, int $process_identifier ]] ) 设置进程的优先级
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
php
source:cnblogs.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!