是定义的操作系统睡眠/挂起期间setTimeout的行为

Is the behaviour of setTimeout across an OS sleep/suspend defined?

本文关键字:setTimeout 挂起 定义 操作系统      更新时间:2023-09-26

我设置了一个setTimeout,例如10s,在这10s期间,我暂停/休眠电脑。唤醒时,以下哪一项为真:-

  1. 超时保证会触发
  2. 保证超时不会触发
  3. 超时可能会触发,也可能不会触发。它是特定于浏览器的

重复出现的setInterval也有同样的问题。保证(不)继续吗。

简短回答

它被定义为在规范中执行。超时请求将进入一个排序队列并轮询,直到它可以被触发。如果系统在恢复时睡眠,它将从停止的地方恢复并恢复轮询。

长答案 可能比任何人都更想知道

最新的(2014年10月28日)定时器规范的工作草案在回答时由w3编写,它将启动。。。只要操作系统在进入睡眠/暂停和唤醒/恢复(范围外)的过程中不出错。这更像是一个操作系统级别的问题,但就w3规范而言,它最终会火起来。

setInterval(...)setTimeout(...)都离开浏览器的window对象实现的相同windowTimer接口。

在这两种情况下,客户端都定义了一个时间间隔或超时请求,方法上下文对该请求执行timer initialization steps,将其添加到活动计时器的列表中,并为计划任务返回句柄

一旦进入活动计时器的列表,系统将对任务进行排队,以便在请求的持续时间内或之后执行(挂起优先级较高的其他任务以及CPU负载)。如果任务无法保留CPU时间,它将轮询/等待,直到可以为止。因此,如果系统在恢复时休眠,它将从停止的地方恢复

为了执行任务,句柄必须存在于活动计时器列表中。任务运行后,如果repeat标志设置为true(如果它是用setInterval(...)创建的),任务将使用相同的参数重新创建,并分配相同的完全相同的句柄。换句话说,它会被添加回队列/列表中,以便在下一个间隔时或之后执行。

以下是Timer规范中关于系统从活动计时器列表中删除项目的唯一注释或备注:

一旦任务被处理,如果重复标志为假,则可以安全地从活动计时器列表中删除句柄条目(在这一点之后,无法检测到条目的存在,因此从技术上讲,无论哪种方式都无关紧要)

根据规范,如果任务运行时它在list of active timers中,它将按预期激发。否则将中止。所以回到我的第一点,如果操作系统在恢复任务的睡眠/挂起过程中没有把事情搞砸,请继续轮询。一旦获得CPU时间,其句柄应仍然存在于活动计时器的列表中,因此在处理时将执行。

我刚刚用这个脚本测试了它:

<html>
<body>
<script>
var d = 120;
var start = new Date ();
document.write(start + " : sleeping for " + d + " seconds");
</script>
<div id='result'><div>
<script>
function cb() {
  var now = new Date ();
  document.getElementById("result").innerHTML = "" + Date () + " : callback fired after " + (now.getTime() - start.getTime()) / 1000 + " seconds";
};
window.setTimeout(cb, d * 1000);
</script>
</body>
</html>

我在Firefox 37.0.1和Chromium 41.0.2272.118(64位)中打开了这个页面,然后暂停了我的机器几分钟。当我恢复时,两个浏览器都等待了几分钟,尽管计时器已经到期。示例输出(机器在Wed 15 Apr 17:52:11 BST 2015恢复):

Wed Apr 15 2015 17:49:13 GMT+0100 (BST) : sleeping for 120 seconds
Wed Apr 15 2015 17:53:47 GMT+0100 (BST) : callback fired after 273.705 seconds

从我目前所读到的内容来看,

  1. 它肯定会着火

然而,延迟并不能得到保证,可能取决于各种因素,并且因浏览器而异。人们已经测试了这种行为。

你可能想看看下面的交叉帖子。约翰·雷西格的一本有趣的读物。