English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Использование сигнальной коммуникации. С помощью команды 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;