立即停止perl守护进程

时间:2014-04-17 07:57:18

标签: linux multithreading perl daemon

我在用Perl编写的Ubuntu上运行一个守护进程,它现在是单线程的。当它启动时,它会执行常见的Proc :: Daemon之类的东西,然后进入一个由布尔值限制的while循环。守护进程启动正常,服务守护进程启动"。但是当我想用"服务守护程序停止"它不会停止。

应该通过使用信号处理程序翻转布尔值来停止:

$SIG{INT} = $SIG{TERM} = $SIG{HUP} = \&signalHandler;

sub signalHandler {
    $continue = 0;
}

不幸的是,主循环也有睡眠。所以守护进程在睡眠结束之前不会结束。我希望守护进程立即结束。但我不想设置非常低的睡眠时间。事实上,我希望能够将睡眠时间设置为几个小时,如果它确定应该这样做的话。

这样做的最佳方式是什么?

我在考虑在主循环中调用某种阻塞函数而不是睡眠。在某个线程死亡之前,此阻塞函数不会返回。然后在信号处理程序中,我会简单地杀死那个睡眠线程。这是一个好方法吗?我怎么做到这一点,我以前从未在Perl中做过多线程。

感谢您的帮助

3 个答案:

答案 0 :(得分:3)

以下是针对这种情况的解决方法:

1.在软件开始运行时创建命名管道,例如mkfifo

2.使用select系统调用替换sleep来电(作为替代方案,您可以使用perl包IO::Select代替select系统调用)。

设置选择以在管道准备好输入时进行监控。

select允许指定超时,就像睡眠一样。

当超时超时或满足文件条件时,select调用返回。

3.如果发生超时,请运行循环的正文代码。如果数据出现在管道上,则终止。

4.要终止,请将数据发送到命名管道。

答案 1 :(得分:1)

您可以将任何与关机相关的清理移动到它自己的子例程(如果您还没有这样做),并让signalHandler()调用该清理子,然后只调用exit。 然后编辑您的开始/停止脚本以发送SIGALRM。 SIGALRM将中断睡眠。如果您的脚本被编辑以捕获它,那么一切都将立即停止。

进一步阅读:sleep()

答案 2 :(得分:1)

除非你做了一些奇怪的改变,否则sleep()函数应该提前唤醒并在收到信号时立即返回。然后,您可以在每次睡眠后更改循环以检查$continue标志,以查看是否收到了关机信号。