PHP对接僵尸,php – 终止从套接字服务器分叉的僵尸子进程

I promise there is a solution at the end 😛

好的,所以在这里我们是10天后,我相信我已经解决了这个问题.我不想添加一个已经很长的帖子,所以我将在这个答案中包括我尝试的一些事情.

If a child as requested by pid has already exited by the time of the call (a so-called

“zombie” process), the function returns immediately. Any system resources used by the child

are freed…

所以我设置我的pcntl_signal()处理程序这样 –

function sig_handler($signo){

global $childProcesses;

$pid = pcntl_waitpid(-1, $status, WNOHANG);

echo "Sound the alarm! ";

if ($pid != 0){

if (posix_kill($pid, 9)){

echo "Child {$pid} has tragically died!".PHP_EOL;

unset($childProcesses[$pid]);

}

}

}

// These define the signal handling

// pcntl_signal(SIGTERM, "sig_handler");

// pcntl_signal(SIGHUP, "sig_handler");

// pcntl_signal(SIGINT, "sig_handler");

pcntl_signal(SIGCHLD, "sig_handler");

要完成,我将包括我用于分支子进程的实际代码 –

function broadcastData($socketArray, $data){

global $db,$childProcesses;

$pid = pcntl_fork();

if($pid == -1) {

// Something went wrong (handle errors here)

// Log error, email the admin, pull emergency stop, etc...

echo "Could not fork()!!";

} elseif($pid == 0) {

// This part is only executed in the child

foreach($socketArray AS $socket) {

// There's more happening here but the essence is this

socket_write($socket,$msg,strlen($msg));

// TODO : Consider additional forking here for each client.

}

// This is where the signal is fired

exit(0);

}

// If the child process did not exit above, then this code would be

// executed by both parent and child. In my case, the child will

// never reach these commands.

$childProcesses[] = $pid;

// The child process is now occupying the same database

// connection as its parent (in my case mysql). We have to

// reinitialize the parent's DB connection in order to continue using it.

$db = dbEngine::factory(_dbEngine);

}

是的…这是1:1的评论与代码的比例:P

所以这看起来很棒,我看到了回音:

Sound the alarm! Child 12345 has tragically died!

但是当套接字服务器循环是下一次迭代时,socket_select()函数失败会抛出此错误:

PHP Warning: socket_select(): unable to select [4]: Interrupted system call…

服务器现在将完全忘记周围的世界的植物人状态,而不是从根终端手动杀死命令以外的任何请求.

我不会搞清楚为什么会发生这种情况,或者我做了什么来调试它…让我们说这是一个令人沮丧的一周…

很多咖啡,眼睛疼痛,10天后…

鼓卷

TL& DR – 解决方案:

在2007年的php套接字文档和this this教程(搜索“好的育儿”)中提到的here,可以简单地“忽略”从子进程(SIGCHLD)传递SIG_IGN的信号到pcntl_signal( )功能 –

pcntl_signal(SIGCHLD, SIG_IGN);

引用该链接的博文:

If we are ignoring SIGCHLD, the child processes will be reaped automatically upon completion.

相信与否 – 我包括pcntl_signal()行,删除所有其他处理程序和处理孩子的事情,它的工作!没有更多的进程留下来!

在我的情况下,我真的不感兴趣我知道一个子进程何时死亡,或者是谁是,我根本不感兴趣 – 只是他们没有挂起来,我的整个服务器崩溃:P

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值