gpt4 book ai didi

php - 随后的 pcntl_signal 信号不会启动处理程序

转载 作者:可可西里 更新时间:2023-11-01 12:39:31 25 4
gpt4 key购买 nike

让我首先对我拥有的代码进行基本描述。我从一个主要的父进程开始(注意:为了简单起见,我没有展示所有功能。如果您需要我随时扩展,请告诉我):

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;
}
}

这是正在发生的事情:

  1. 我启动脚本并正确获取进程(例如 Parentpid:2、childpid:3)
  2. 然后我向父进程发送一个 SIGHUP 信号,它正确地杀死并启动一个新的子进程(例如 Parentpid:2,childpid:4)
  3. 然后我向父进程发送第二个 SIGHUP 信号,它会正确地尝试并添加一个新的子进程,但它拒绝终止第二个子进程。 (例如 Parentpid:2, undyingchildpid:4, newchildpid:5)

让我知道是否需要更多详细信息/没有意义。我不明白为什么第一次它会正确地杀死 child ,但第二次却没有。

甚至更奇怪的部分是,当我改变它以便我改变我的重启处理程序以便它一直试图用 SIGINT 杀死 child 时,它每次都会失败,但是当我向它发送 SIGKILL 命令时它会杀死 child 过程:

if($time_passed > 60){
posix_kill($pid, SIGKILL);
}

我需要 child 能够被 SIGINT 杀死,以便正确处理它。我不想只是 SIGKILL 它。是否有任何理由说明为什么第二次 SIGINT 不起作用,但 SIGKILL 会起作用?

最佳答案

首先,你不需要 fork 。您的代码在 child 内部执行一个 exec,您基本上可以在不 fork 的情况下运行 exec,并且操作系统会将您的命令作为 child 生成。如果你想使用 fork,只需 include 子文件而不是执行。

public function create_fork(){
//no need to actually fork!
pcntl_exec('/usr/bin/php', array('/domain/dev/www/index.php','holder','process'));
}

//if you want to fork, better do it like this :


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
include '/domain/dev/www/index.php';
SomeClass::someMethod();
exit(0);
}
}

另外,使用fork时,需要为子进程waitpid。所以,在你的代码中你需要插入类似的东西:

//somewhere in a loop : 
$pidOfExittedChild = pcntl_waitpid (-1, $status, WNOHANG);
if ($pidOfExittedChild) {
//a child has exitted, check its $status and do something
}

查看更多信息: http://php.net/manual/en/function.pcntl-waitpid.php

关于php - 随后的 pcntl_signal 信号不会启动处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9675370/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com