代码之家  ›  专栏  ›  技术社区  ›  Ricardo Marimon

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

  •  5
  • Ricardo Marimon  · 技术社区  · 14 年前

    #!/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 使用向进程发送信号 kill -USR1 xxxxx . 结果不是我所期望的:

    Sat Oct 30 21:08:25 2010 doing it 1
    Sat Oct 30 21:08:25 2010 doing it 0

    我得到两个连续的条目,一个来自信号处理子程序,另一个来自不断运行的循环。似乎每当 1美元

    怎么回事?

    1 回复  |  直到 12 年前
        1
  •  8
  •   Ether    14 年前

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

    如果进程接收到诸如“SIGALRM”的信号,则可能被中断。

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

    while (1)
    {
        my $actual = sleep(30);
        sleep(30 - $actual) if $actual < 30;
    }
    

    perldoc perlipc ,在几乎所有的unix编程书籍中 W. Richard Stevens . :)