Позвольте мне начать с основного описания кода, который у меня есть. Я начинаю с основного родительского процесса (ПРИМЕЧАНИЕ: я не показываю все функции для простоты. Дайте мне знать, если вам нужно, чтобы я расширился в любой момент):
declare(ticks=1);
pcntl_signal(SIGHUP, array('forker', 'restartSignalHandler'));
if(forker_is_not_running()){
new Forker();
}
class Forker {
private $active_forks = array();
private $parent_pid = null;
public function __construct(){
$this->parent_pid = getmypid();
$this->create_fork();
$this->wait_for_active();
}
public function wait_for_active(){
while(!empty($this->active_forks)){
foreach($this->active_forks as $k=>$fork){
if($this->fork_no_longer_running($fork)){
unset($this->active_forks[$k]);
}
}
}
}
// Pseudo code
public function fork_no_longer_running($pid){
// return true if 'ps -elf | grep $pid' doesn't returns only the grep command
// else return false (aka the fork is still running)
}
public function create_fork(){
$pid = pcntl_fork();
if($pid == -1){
posix_kill($this->parent_pid, SIGTERM);
} else if($pid){
// add the pid to the current fork
$this->active_forks[] = $pid;
} else {
// Run our process
pcntl_exec('/usr/bin/php', array('/domain/dev/www/index.php','holder','process'));
exit(0);
}
}
public function restartSignalHandler(){
$forks = $this->active_forks;
foreach($forks as $pid){
$this->create_fork();
posix_kill($pid, SIGINT);
}
}
}
class holder {
public function process(){
$x = new Processor();
}
}
class Processor {
public function __construct(){
pcntl_signal(SIGINT, array($this, "shutdownSignalHandler"));
}
public function shutdownSignalHandler(){
echo "Shutting down";
exit;
}
}
Вот что происходит:
- Я запускаю свой скрипт и правильно получаю процессы (например, Parentpid:2, childpid:3)
- Затем я отправляю родителю сигнал SIGHUP, и он правильно убивает и запускает новый дочерний процесс (например, Parentpid: 2, childpid: 4).
- Затем я отправляю родителю второй сигнал SIGHUP, и он корректно пытается добавить новый дочерний процесс, но отказывается убивать второй дочерний процесс. (например, Parentpid:2, undyingchildpid:4, newchildpid:5)
Дай мне знать, если это требует дополнительных подробностей/не имеет смысла. Я не могу понять, почему в первый раз это правильно убивает детей, а во второй раз - нет.
Еще более СТРАННАЯ часть заключается в том, что когда я меняю его так, чтобы я изменил свой обработчик перезапуска, чтобы он продолжал пытаться убить ребенка с помощью SIGINT, он каждый раз терпел неудачу, но когда я отправляю ему команду SIGKILL, он убивает дочерний процесс:
if($time_passed > 60){
posix_kill($pid, SIGKILL);
}
Мне нужно, чтобы ребенка можно было убить с помощью SIGINT, чтобы правильно с ним справиться. Я не хочу просто SIGKILL. Есть ли причина, по которой второй раз SIGINT не сработает, а SIGKILL сработает?