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

ben*_*kah 3 perl

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

我可以使用这个shell管道检测到这一点(来自其他问题的想法):

strace perl -e 'sleep 1' 2>&1 | grep 'sleep\|alarm'
Run Code Online (Sandbox Code Playgroud)

如果通过警报实现睡眠,您将在输出中看到警报系统调用.否则你会看到一个不同的睡眠系统调用,如下面的Ubuntu 10.04.2:

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

但是,我正在寻找简洁的纯perl代码(最好是一个衬垫)来检测它以及你应该看到的警报是否存在睡眠的基础以及如果没有睡眠会发生什么.

注意:

  • 这个问题并不是在寻找如何防止中断睡眠的警报.有人问过并回答过.
  • 不寻找通过警报实现睡眠的解决方法.也许你可以在另一个问题上提出并回答这个问题.
  • 这不是一个高尔夫问题.我不是在寻找最简洁的方式.
  • 我不会为任何生产代码做这个只是好奇心.

ben*_*kah 6

关于SIGALRM维基百科条目指出:

[SIGALRM]有时用于实现睡眠功能; 因此,程序不能可靠地使用警报来从睡眠引起的延迟中"唤醒".

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

 perl -e 'alarm 1; sleep 2; print "slept\n"';
Run Code Online (Sandbox Code Playgroud)

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

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

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