Perl:在分叉的子进程中安装信号处理程序

时间:2011-04-01 19:24:17

标签: perl exec fork signal-handling

我发现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,孩子可以照顾好自己。) }

2 个答案:

答案 0 :(得分:2)

在Unix系统上,你可以让exec'd进程忽略信号(除非进程选择覆盖你所说的),但是你不能强迫它为它设置处理程序。您可以做的最多就是让相关信号由默认处理程序处理。

如果你考虑一下,你会明白为什么。要安装信号处理程序,您必须提供一个函数指针 - 但执行exec()的进程无法指定其中一个函数,因为它们不会作为exec'd进程的一部分存在,并且它不能指定一个exec'd进程函数,因为它们不作为exec'ing进程的一部分存在。同样,您不能在执行过程中注册atexit()个处理程序,这些处理程序将由执行过程授予。

关于编程问题,锁文件通常包含持有锁的进程的进程ID(pid)是一个很好的理由;它允许您检查该过程是否仍然存在,即使它不是您的孩子。您可以从锁定文件中读取pid,然后使用kill(pid, 0),它将告诉您该过程是否存在,并且您可以发出信号而不实际发送任何信号。

答案 1 :(得分:1)

一种方法是使用两个叉子。

第一个fork会创建一个子进程,负责在父进程死亡时清理锁文件。这个过程也会分叉一个孙子,它将执行长时间运行的命令。