当 perl 接收到任何信号时睡眠会被中断吗?

发布于 2024-09-29 18:05:36 字数 1080 浏览 4 评论 0原文

我有这个简单的 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

当我使用 kill -USR1 xxxxx 向进程发送 USR1 信号时,问题就出现了。输出不是我所期望的:

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

我得到两个连续的条目,一个来自信号处理子例程,另一个来自不断运行的循环。似乎只要收到 USR1 信号,睡眠就会被中断。

到底是怎么回事?

I have this simple perl daemon:

#!/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");
}

But there is something that is not working right.

When the daemon starts, it logs every 30 seconds without the notification as expected:

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

The problem comes when I send the USR1 signal to the process using kill -USR1 xxxxx. The output is not what I expect:

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

I get two continuous entries, one from the signal handling subroutine and another form the ever running loop. It seems as if the sleep gets interrupted whenever the USR1 signal is received.

What is going on?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

送君千里 2024-10-06 18:05:36

睡眠被中断,因为您的程序将处理传入信号,但循环将继续(返回睡眠)直到收到 TERM 信号。这是 sleep() 函数的记录行为:

如果进程收到“SIGALRM”等信号,可能会被中断。

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

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

PS。您可以在 perldoc perlipc 以及 W.理查德·史蒂文斯。 :)

The sleep is getting interrupted in the sense that your program will handle the incoming signal, but the loop will continue (going back to sleep) until a TERM signal is received. This is documented behaviour for the sleep() function:

May be interrupted if the process receives a signal such as "SIGALRM".

Note that if you need to sleep for 30 seconds, even if interrupted by a signal, you can determine the number of seconds slept and then sleep again for the remainder:

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

PS. You can read more about signal handling in perldoc perlipc, and in virtually any unix programming book by W. Richard Stevens. :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文