English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Base de la communication de processus PHP par signaux

Pour la communication par signaux, vous pouvez utiliser kill -l pour voir le type de signaux du système actuel.
Pour consulter les détails de chaque signal, veuillez lire cet article : https://fr.oldtoolbag.com/article/106040.htm
Lors de l'utilisation des signaux, vous pouvez utiliser php --Pour vérifier la version actuelle de PHP, il a été décidé de la manière de communication des signaux entre processus.

[root@roverliang ipc]# php --version
PHP 5.6.24 (cli) (construit: Août 15 2016 19:14:02)
Droit d'auteur (c) 1997-2016 Le Groupe PHP
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies

Pour utiliser la fonction pcntl_signal_dispatch, il est nécessaire que la version PHP (PHP 5 >= 5.3.0, PHP 7)

Si la version PHP est inférieure à5.3.Certaines grandes entreprises peuvent être inférieures à cette version. À ce moment-là, declare(ticks=1), ce qui signifie que chaque fois qu'une instruction de bas niveau est exécutée,
vérifier si ce signal apparaît. Une présentation détaillée peut être consultée à https://fr.oldtoolbag.com/article/48340.htm

L'explication officielle est la suivante : Tick (période d'horloge) 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 declare. La valeur de N est spécifiée dans la partie directive de declare par ticks=N.

Alors, qu'est-ce qu'une instruction de bas niveau ? Voici un exemple de code :

  for ($i = 0; $i < 3; $i++) {
    echo $i.PHP_EOL;
  }

Alors, ce boucle for contient trois instructions de bas niveau. Chaque fois qu'il sort une $i, il vérifie s'il y a eu un événement enregistré, ce qui est compréhensible, donc l'efficacité est assez basse. Donc, si vous détectez que votre PHP est supérieur ou égal à5.3 。Utilisez donc pcntl_singal_dispath pour effectuer la distribution de signaux.

Le processus principal enregistre des fonctions de traitement de signaux lors du lancement.

/**
 * @param $signal Signal
 */
function signalHandal($signal)
{
  switch ($signal) {
    case SIGINT:
      //faire quelque chose
      break;
    case SIGHUP:
      //faire quelque chose
      break;
    default :
      //faire quelque chose
      break;
  }
}

Ensuite, liez le gestionnaire de signal à la fonction de traitement de signal :

//Installer différents gestionnaires de signaux en fonction de différents signaux
pcntl_signal(SIGINT, 'signalHandal');
pcntl_signal(SIGHUP, 'signalHandal');
pcntl_signal(SIGUSR1, 'signalHandla');

Dans le processus fils, écouter le signal, appeler la fonction de traitement de signal pré-installée si ce signal apparaît

//allouer un signal.
pcntl_signal_dispatch($signal);

Rassemblons nos idées :
1、définir la fonction qui doit traiter les événements nécessaires à l'occurrence du signal
2、lier un signal à une fonction de traitement de signal, ce qui est appelé installation de signal.
3、écouter ou distribuer des signaux, appeler les signaux installés lors de l'apparition d'un signal.

Bien comprendre le concept des signaux mentionnés précédemment, regardons un exemple :

<?php
$parentpid = posix_getpid();
echo "parent progress pid:{$parentpid}\n";
//Définissez une fonction gestionnaire de signaux
function sighandler($signal) {
  if ($signal == SIGINT) {
    $pid = getmypid();
    exit("{$pid} process, Killed!".PHP_EOL);
  }
}
//php version < 5.3 .Vérifiez si ce signal apparaît après chaque instruction de bas niveau. Cela entraîne une grande perte d'efficacité.
//declare(ticks=1);
$child_list = [];
//Enregistrement d'un gestionnaire de signaux. Appel de la fonction définie lorsque ce signal est émis
pcntl_signal(SIGINT, 'sighandler');
for($i = 0; $i < 3; $i++) {
  $pid = pcntl_fork();
  if ($pid == 0) {
    //Processus fils
    while (true) {
      //Appel du gestionnaire de signaux installé pour détecter s'il y a de nouveaux signaux en attente de dispatching
      pcntl_signal_dispatch();
      echo "I am child: ".getmypid(). " and i am running !".PHP_EOL;
      sleep(rand(1,3));
    }
  }
    $child_list[] = $pid;
  } else {
    die('fork fail!'.PHP_EOL);
  }
}
sleep(5);
foreach ($child_list as $key => $pid) {
  posix_kill($pid, SIGINT);
}
sleep(2);
echo "{$parentpid} parent is end".PHP_EOL;
Vous pourriez aussi aimer