我发现Managing Signal Handling for daemons that fork()中的答案对我正在做的事情非常有帮助。我不确定如何解决
"因此,您需要在启动时在已执行的过程中安装任何信号处理"
我无法控制启动过程。有没有办法让我在fork的父级exec
ed上强制使用一些信号句柄?
修改: {
我正在编写一个监视长时间运行进程的Perl模块。而不是
system(<long-running cmd>);
您使用
my_system(<ID>, <long-running cmd>);
我为<ID>
创建了一个锁定文件,如果当前正在使用匹配的ID运行,请不要再通过my_system(<ID>...)
。
父fork / execs <long-running cmd>
并且更改了在终止时清理锁文件。我想让孩子自给自足,以便父母可以退出(或者如果父母得到kill -9
,孩子可以照顾好自己。)
}
答案 0 :(得分:2)
在Unix系统上,你可以让exec'd进程忽略信号(除非进程选择覆盖你所说的),但是你不能强迫它为它设置处理程序。您可以做的最多就是让相关信号由默认处理程序处理。
如果你考虑一下,你会明白为什么。要安装信号处理程序,您必须提供一个函数指针 - 但执行exec()
的进程无法指定其中一个函数,因为它们不会作为exec'd进程的一部分存在,并且它不能指定一个exec'd进程函数,因为它们不作为exec'ing进程的一部分存在。同样,您不能在执行过程中注册atexit()
个处理程序,这些处理程序将由执行过程授予。
关于编程问题,锁文件通常包含持有锁的进程的进程ID(pid)是一个很好的理由;它允许您检查该过程是否仍然存在,即使它不是您的孩子。您可以从锁定文件中读取pid,然后使用kill(pid, 0)
,它将告诉您该过程是否存在,并且您可以发出信号而不实际发送任何信号。
答案 1 :(得分:1)
一种方法是使用两个叉子。
第一个fork会创建一个子进程,负责在父进程死亡时清理锁文件。这个过程也会分叉一个孙子,它将执行长时间运行的命令。