【问题标题】:How can I tell if sleep is implemented using alarm on my system in perl?如何判断是否在 perl 中使用系统上的警报实现了睡眠?
【发布时间】:2011-08-31 19:06:09
【问题描述】:

perl 文档中有很多地方警告不要将睡眠与警报结合使用,因为睡眠可以通过警报实现。但是,如果您的系统出现这种情况,文档并没有说明会出现什么症状。

我可以使用这个 shell 管道检测到这一点(来自this other question 的想法):

strace perl -e 'sleep 1' 2>&1 | grep 'sleep\|alarm'

如果睡眠是通过警报实现的,您将在输出中看到警报系统调用。否则,您将看到来自 Ubuntu 10.04.2 的不同睡眠系统调用,如下所示:

execve("/usr/bin/perl", ["perl", "-e", "sleep 1"], [/* 26 vars */]) = 0
nanosleep({1, 0}, 0xbfacba54)           = 0

但是,我正在寻找简洁的纯 perl 代码(最好是单行代码)来检测它以及您应该期望看到的警报是否是睡眠的基础以及如果不是睡眠的预期会发生什么。

注意:

  • 此问题不是在寻找如何防止闹钟中断睡眠。那是asked and answered
  • 不寻找通过警报实现睡眠时的解决方法。也许您可以在另一个问题上提出并回答。
  • 这不是 perl-golfing 问题。我不是在寻找最简洁的方式。
  • 我不会为任何生产代码这样做,这只是出于好奇。

【问题讨论】:

    标签: perl


    【解决方案1】:

    wikipedia entry on SIGALRM 声明:

    [SIGALRM] 有时用于实现睡眠功能;因此,程序无法可靠地使用闹钟从睡眠造成的延迟中“唤醒”

    基于此,我猜测以下将检测是否通过警报实现睡眠:

     perl -e 'alarm 1; sleep 2; print "slept\n"';
    

    如果通过警报实现睡眠,则输出将“睡眠”,因为对睡眠的调用将重置警报并在新的 SIGALRM 到达时接管处理。如果以另一种方式实现睡眠,则输出将是“闹钟”,表明默认的警报处理程序已被触发。

    很遗憾,我无法测试这个案例,因为我还没有找到通过闹钟实现睡眠的系统。

    (有趣的是,维基百科条目引用了睡眠功能的 perl 文档)

    【讨论】:

    • 看起来有些版本的 Solaris 就是这样的例子。见:stackoverflow.com/questions/1085215/…
    • @benrifkah,鉴于此,链接线程中的大多数解决方法根本没有帮助,因为他们试图解决相反的情况:sleep 被信号打断(如果你定义了一个信号处理程序)。
    • @ikegami,感谢您指出这一点。我误读了那个问题。尽管作者对其问题原因的理解不正确,但它提到了警报和睡眠交互。我会更新我原来的问题。
    猜你喜欢
    • 2010-09-22
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多