【发布时间】:2012-01-30 13:01:00
【问题描述】:
我正在开发一个使用fork() 和 exec 来创建子进程的服务器代码。子进程的PID在fork()成功时注册,在CHILD信号被捕获时清理。
如果服务器需要停止,所有程序都会被终止,最终会发出 KILL 信号。现在,这通过遍历所有已注册的 PID 并等待 CHILD 信号处理程序删除 PID 来工作。如果子程序没有正确退出,这将失败。因此,我想将kill 与waitpid 结合使用,以确保清理并记录PID 列表并执行其他操作。
考虑下一个代码示例:
kill(pid, SIGKILL);
waitpid(pid, NULL, WNOHANG);
摘自waitpid(2):
waitpid():成功时,返回状态发生变化的子进程ID;如果指定了 WNOHANG 并且有一个或多个孩子 pid 指定的存在,但尚未改变状态,则返回 0。出错时返回-1。
pid 给出的进程总是在下一个函数启动之前就已经过去了吗?在上述情况下waitpid 是否总是返回-1?
【问题讨论】:
-
KILL 信号相当残酷,为什么不是 INT 或 HUP?还有,
kill系统调用的返回码是什么? -
"等待 CHILD 信号处理程序..." -- SIGKILL 没有信号处理程序,你知道吗?除 SIGSTOP 和 SIGKILL 之外的所有信号都将执行
sigaction设置的操作(例如调用处理程序)或默认值。 SIGSTOP 只是停止,而 SIGKILL 只是终止该进程。总是。没有处理或条件。 (例外是kill系统调用失败,因为您没有足够的权限。) -
@Damon:
SIGKILL不能被目标进程忽略,没错。但这不是问题/问题。源进程上的kill(2)系统调用可以在目标进程上下文中(由内核)评估信号之前返回。kill(2)基本上是一个非常简单的异步通信,必须按照所有含义进行处理。 -
是的,除非别无选择,否则不要使用
SIGKILL。如果要指示进程终止,请使用SIGTERM。 -
@fge 如果孩子在 SIGTERM 上响应不够快,它最终发送 SIGKILL。