如何使用perl中的系统警报来判断睡眠是否已实现?

时间:2011-08-31 19:06:10

标签: perl

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
  • 不寻找通过闹钟实现睡眠的解决方法。也许你可以在另一个问题上提出并回答这个问题。
  • 这不是一个高尔夫问题。我不是在寻找最简洁的方式。
  • 我不会为任何生产代码执行此操作,这只是一种好奇心。

1 个答案:

答案 0 :(得分:6)

wikipedia entry on SIGALRM州:

  

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

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

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

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

不幸的是,我无法测试这种情况,因为我还没有找到一个通过警报实现睡眠的系统。

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