【发布时间】:2012-04-16 02:44:17
【问题描述】:
免责声明
我很清楚 PHP 在这种情况下可能不是套接字服务器的最佳选择。请不要建议 不同的语言/平台 - 相信我 - 我听说过 方向。
在 Unix 环境 中工作并使用 PHP 5.2.17,我的情况如下 - 我在 PHP 中构建了一个与 flash 客户端通信的套接字服务器。我的第一个问题是每个传入的连接都会阻塞顺序连接,直到它完成处理。我通过使用 PHP 的 pcntl_fork()解决了这个问题。我成功地生成了许多子进程(将它们的 PID 保存在父进程中),它们负责向其他客户端广播消息,因此“释放”父进程并允许它继续处理下一个连接[s]。
我现在的主要问题是处理/处理这些死/僵尸子进程的集合并终止它们。我已经(一遍又一遍地)阅读了pcntl_fork() 的相关 PHP 手册页,并意识到 父进程负责清理其子进程。当子进程执行exit(0) 时,父进程从其子进程接收信号。我能够使用pcntl_signal() 函数“捕捉”该信号来设置信号处理程序。
我的 signal_handler 看起来像这样:
declare(ticks = 1);
function sig_handler($signo){
global $forks; // this is an array that holds all the child PID's
foreach($forks AS $key=>$childPid){
echo "has my child {$childPid} gone away?".PHP_EOL;
if (posix_kill($childPid, 9)){
echo "Child {$childPid} has tragically died!".PHP_EOL;
unset($forks[$key]);
}
}
}
我确实看到了两个 echo 的,包括需要删除的相关且正确的子 PID,但似乎
posix_kill($childPid, 9)
我理解为 kill -9 $childPid 的同义词返回 TRUE,尽管它实际上并未删除进程...
成功时返回 TRUE,失败时返回 FALSE。
我正在使用ps 命令监视子进程。它们在系统上显示如下:
web5 5296 5234 0 14:51 ? 00:00:00 [php] <defunct>
web5 5321 5234 0 14:51 ? 00:00:00 [php] <defunct>
web5 5466 5234 0 14:52 ? 00:00:00 [php] <defunct>
如您所见,所有这些进程都是父进程的子进程,其 PID 为5234
我的理解是否遗漏了什么?我似乎已经设法让一切正常工作(确实如此),但我在系统上留下了无数的僵尸进程!
我的僵尸启示录计划坚如磐石 -
但是当sudo kill -9 没有杀死僵尸子进程时,我到底能做什么?
10 天后更新
如果您仍然能够忍受我的胡言乱语proceed at will,我在进行了一些额外的研究后自己回答了这个问题。
【问题讨论】:
-
@jon - 删除我能理解的图像(如果它真的困扰你的话)但我们正在处理所谓的僵尸进程。已终止但仍在系统上等待其父级清理它们的进程。如果您不是 100% 了解帖子的内容,请不要删除文字或编辑帖子。
-
我不是 php 专家,但这可能与您的子进程本身是基于 PHP 的事实有关,并且当父进程仍在使用的 PHP 运行时停止时将不复存在...为了测试这个想法,创建非基于 PHP 的孩子(即使
ls也应该适合这样的测试)。 -
+1 用于进行自己的研究、解释您的发现并仅在没有明显问题时发布。
-
@str - 谢谢:P 我已经在键盘上敲了几个小时:P 是时候发布问题了......
-
@Lix,啊,那甚至不是我……我只是删除了图像。 Err wait - 历史显示我确实更改了标题。哇,不知道为什么会这样,我当然不打算这样做。我很抱歉 - 这当然是合适的。
标签: php sockets child-process