Linux 在perl中接收到任何信号时,睡眠是否会中断?

Linux 在perl中接收到任何信号时,睡眠是否会中断?,linux,perl,signals,daemon,Linux,Perl,Signals,Daemon,我有一个简单的perl守护程序: #!/usr/bin/perl use strict; use warnings; use Proc::Daemon; Proc::Daemon::Init; my $continue = 1; $SIG{TERM} = sub { $continue = 0 }; $SIG{USR1} = sub { do_process(1) }; # basic daemon

我有一个简单的perl守护程序:

#!/usr/bin/perl

use strict;
use warnings;
use Proc::Daemon;

Proc::Daemon::Init;

my $continue = 1;

$SIG{TERM} = sub { $continue = 0 };
$SIG{USR1} = sub { do_process(1) };

# basic daemon                                                                                    

boxesd_log("started boxesd");

while ($continue) {
    do_process(0);
    sleep(30);
}

boxesd_log("finished boxesd");

exit(0);

# required subroutines                                                                            

sub do_process {
    my ($notified) = @_;
    boxesd_log("doing it $notified");
}
但是有一些事情是不正常的

当守护进程启动时,它会每30秒记录一次,而不会像预期的那样发出通知:

Sat Oct 30 21:05:47 2010 doing it 0 Sat Oct 30 21:06:17 2010 doing it 0 Sat Oct 30 21:06:47 2010 doing it 0 我得到两个连续的条目,一个来自信号处理子程序,另一个来自不断运行的循环。似乎每当收到
USR1
信号时,睡眠就会中断


发生了什么?

睡眠被中断,因为您的程序将处理传入的信号,但循环将继续(返回睡眠),直到收到一个术语信号。这是功能的记录行为:

如果过程接收到诸如“SIGALRM”之类的信号,则可能会中断

请注意,如果您需要睡眠30秒,即使被信号中断,您也可以确定睡眠的秒数,然后在剩余的时间内再次睡眠:

while (1)
{
    my $actual = sleep(30);
    sleep(30 - $actual) if $actual < 30;
}
while(1)
{
我的$actual=睡眠(30);
如果$actual<30,则睡眠(30-$actual);
}

另外,您可以在中阅读更多关于信号处理的信息,几乎可以在任何unix编程书籍中阅读。:)

您没有检查第二次
睡眠是否也被中断。要正确处理它,您需要某种循环,而不仅仅是
if
@mark4o:infinite循环,直到信号中断它,是的,这通常是守护进程所做的。(为了清晰起见,我删除了
$continue
变量,因为它与
睡眠
在各种情况下的行为这一核心问题无关。显然,人们可能希望使实际代码更加复杂,例如,如cjm所述,在第二次中断时再次睡眠。)哦,我以为这个循环应该取代睡眠(30)
,而不是整个主循环。在这种情况下,我同意cjm,而且对
do\u process
的调用也丢失了。@马克:我确信你可以假装
do\u process()
调用在它应该在的地方:p$sleep=30;while($sleep>0)$sleep-=sleep($sleep);
while (1)
{
    my $actual = sleep(30);
    sleep(30 - $actual) if $actual < 30;
}