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

Основы процесса通信 в PHP с использованием сигналов

Использование сигнальной коммуникации. С помощью команды kill -l можно посмотреть текущие типы сигналов в системе.
Подробное значение каждого сигнала можно увидеть в моей статье: https://ru.oldtoolbag.com/article/106040.htm
При использовании сигналов можно проверить текущую версию PHP с помощью php --version. Принято решение о том, как будет производиться сигнальная коммуникация между процессами.

[root@roverliang ipc]# php --version
PHP 5.6.24 (cli) (собран: Aug 15 2016 19:14:02)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies

Использование функции pcntl_signal_dispatch требует PHP версии (PHP 5 >= 5.3.0, PHP 7)

Если версия PHP меньше 5.3, некоторые крупные компании могут быть ниже этой версии. В этом случае используется declare(ticks=1), что означает, что при выполнении каждого низкоуровневого指令
проверяется, arises ли этот сигнал. Подробное описание можно найти по адресу https://ru.oldtoolbag.com/article/48340.htm

Официальное объяснение следующим образом: Tick (цикл таймера) - это событие, которое возникает в каждом执行的 N низкоуровневых инструкций в разделе кода declare. Значение N указывается в разделе directive directive ticks=N.

Что такое низкоуровневые инструкции? Вот пример кода:

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

Тогда этот цикл for содержит три низкоуровневых инструкции. При каждом выводе $i будет проверяться, произошли ли зарегистрированные события, можно представить себе, что эффективность низкая. Поэтому, если обнаружено, что версия PHP больше или равна 5.3, используйте pcntl_singal_dispath для выполнения сигнальной рассылки.

Основной процесс регистрирует некоторые функции обработки сигналов при запуске.

/**
 * @param $signal сигнал
 */
function signalHandal($signal)
{
  switch ($signal) {
    case SIGINT:
      //do something
      break;
    case SIGHUP:
      //do something
      break;
    default :
      //do something
      break;
  }
}

Затем привяжем обработчики сигналов к функциям обработки сигналов:

//Установить различные обработчики сигналов в зависимости от различных сигналов
pcntl_signal(SIGINT, 'signalHandal');
pcntl_signal(SIGHUP, 'signalHandal');
pcntl_signal(SIGUSR1, 'signalHandla');

В подпроцессе слушание сигналов, если arises этот сигнал, вызовем предварительно установленный обработчик сигнала

//分配信号。
pcntl_signal_dispatch($signal);

Давайте организуем наши мысли:
1. Определение функции обработки событий, необходимых для генерации сигнала
2. Привязка сигналов к функциям обработки сигналов, что называется установкой сигнала.
3. Слушание или分发 сигналов, вызов уже установленных сигналов при的出现 сигнала.

Поняв上面的 сигнальные концепции, давайте рассмотрим демонстрацию:

<?php
$parentpid = posix_getpid();
echo "parent progress pid:{$parentpid}\n";
// определение сигнальной обработчик функции
function sighandler($signal) {
  if ($signal == SIGINT) {
    $pid = getmypid();
    exit("{$pid} process, Killed!".PHP_EOL);
  }
}
//php version < 5.3 . каждый раз при выполнении низкоуровневой команды проверяется, поступил ли сигнал. Это приводит к значительным потерям производительности.
//declare(ticks=1);
$child_list = [];
// регистрация сигнального обработчика. При получении сигнала вызывается определенная функция
pcntl_signal(SIGINT, 'sighandler');
for($i = 0; $i < 3; $i++) {
  $pid = pcntl_fork();
  if ($pid == 0) {
    // подпроцесс
    // вызов уже установленного обработчика сигналов для проверки наличия новых сигналов, ожидающих dispatching
      pcntl_signal_dispatch();
      echo "I am child: ".getmypid(). " and i am running !".PHP_EOL;
      sleep(rand(1,3));
      elseif($pid > 0) {
    }
  }
    $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;
Рекомендуем вам