【问题标题】:setTimeout behaves differently on Mac OS and Linux when using libfaketime使用 libfaketime 时,setTimeout 在 Mac OS 和 Linux 上的行为不同
【发布时间】:2018-11-09 14:54:56
【问题描述】:

当使用libfaketime改变进程的时间速度时,setTimout设置的超时时间在Linux下按照修改后的时间过期,而在Mac OS下按照原系统时间过期。

在 Mac 操作系统中:

DYLD_INSERT_LIBRARIES=src/libfaketime.1.dylib DYLD_FORCE_FLAT_NAMESPACE=y FAKETIME="@2020-12-24 00:00:00 x3600" node

> setTimeout(() => {console.log('hello');}, 3600 * 1000); // Takes an hour

在 Linux 中:

LD_PRELOAD=src/libfaketime.1.so FAKETIME="@2020-12-24 00:00:00 x3600" node

> setTimeout(() => {console.log('hello');}, 3600 * 1000); // Takes a second

在调查这个问题时,我注意到libcclock_gettime 函数在 Linux 下被 node.js (libuv?) 轮询,但在 Mac OS 下运行时不会调用此函数。 (我在libfaketime 函数中添加了一些printfs)

node.js(libuv?)的实现有什么不同导致 Mac OS 和 Linux 之间的行为差​​异?为什么会存在这种实施差异?

我所做的另一个观察是,当使用 libfaketime 冻结时间时,setImmediatesetTimeout(cb, 0) 在 Linux 下的行为不同,因为在使用 setImmediate 时会运行回调,但在使用 setTimeout(cb, 0) 时不会运行回调。

【问题讨论】:

    标签: node.js linux macos settimeout libuv


    【解决方案1】:

    这绝对是 libuv 的不同之处。达尔文没有support CLOCK_MONOTONIC*,因此mach_absolute_time() must be called 是为了获取当前时间。这最终绕过了libfaketime,导致客户端代码在 OS X 上实时运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-02
      • 2015-08-11
      • 1970-01-01
      • 2023-03-18
      相关资源
      最近更新 更多