1

在 Solaris 10 上,我有一个父进程和子进程。我用 kill -KILL 杀死子进程。我希望在父进程中尽可能快地检测到这一点(这是一个主/从系统,目标是让父进程请求其备份尽快接管)。父进程需要知道子进程已经开始退出(不需要等到子进程退出)。

在我正在使用的系统中,我看到发送 SIGKILL 和接收 SIGCHLD 的父进程之间有大约 200 毫秒的延迟。我不认为我可以减少这个时间,仅仅是因为子进程的大小和退出所需的时间 - 如果我错了,请纠正我。

我认为我的选择是: - 不要向孩子发送 SIGKILL。而是向父进程发送一个信号,以便它可以杀死子进程(因此立即知道子进程正在被终止)。这并不理想,因为某些“kill -KILL”命令超出了我的控制范围,因此我无法将它们替换为对父级的不同信号。-- 挂钩子进程的终止处理(我认为这是不可能的,因为 SIGKILL 无法被捕获)。——还有什么想法吗?

感谢您的任何建议。尼克B

4

4 回答 4

0

这是一个猜测,但是父进程是如何检测到 SIGCHLD 的呢?如果您正在使用信号处理程序,则可以通过使用专用信号线程来获得一些速度。

基本上,您启动一​​个单独的线程来处理信号。所有线程(包括信号线程)都应调用pthread_sigmask()以阻止接收 SIGCHLD。然后,信号线程sigwait()使用包含 SIGCHLD 的掩码进行调用。sigwait() 将阻塞直到收到 SIGCHLD,然后在收到信号时返回。

使用信号线程的主要优点是您可以在某种主循环中处理信号,而不受信号处理程序的限制或让信号中断进程可能正在做的其他事情。我的疯狂猜测是,内核使用这种方法向线程传递信号也可能更便宜。

于 2010-02-25T20:41:19.520 回答
0

您可以使用waitpid () 或 waitid() 来检测子进程的状态变化,而不是使用信号来捕获被杀死的子进程。在任何情况下,您都应该调用其中之一来获取孩子的 pid ......

然后,您可以忽略 SIGCHLD,并获得避免异步编码的额外好处。

paxdiablo 关于使用信号量的建议实际上也可能是你想要的:在启动时,一个孩子锁定一个信号量。如果您运行两个子进程,则一个将运行,一个将在信号量上等待。一旦第一个被杀死,第二个开始运行。

于 2010-02-23T11:27:15.687 回答
0

我不确定您是否会比 SIGCHLD 的交付快得多。如果可能的话,您可能想考虑将应用程序重新架构为主/多从应用程序。

如果您使用 1 个 master 和 5 个 slave 运行,那么丢失一个 slave 将导致容量下降 20%,而不是全部丢失。并且希望主人能够在它被注意到之前足够快地让另一个奴隶起来。

另一个可能的好处是让备用从机等待,已经开始但等待信号量或其他信号开始做真正的工作。即使您不能并排运行多个从属服务器,这也可能会有所帮助,因为它将至少消除部分延迟(等待进程加载)。只需在 SIGCHLD 出现后立即通知备用孩子开始。

于 2010-02-23T10:41:30.893 回答
0

您可以使用不太广为人知的 Solaris功能。在您的父进程中,door_create使用DOOR_UNREF属性创建门,这意味着:

当引用此门的描述符数量降至 1 时,对门进行特殊调用。

然后 fork,所以你有两个对门描述符的引用。当您的子进程死亡时,会在父进程中调用门函数,因为门的描述符引用下降到一个。

Solaris 门的本意是超快,但老实说,在这种特殊情况下,我从未测量过交货时间。请让我知道这对你有没有用。

于 2010-06-25T20:14:26.283 回答