当使用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
在调查此问题时,我注意到 libc
的 clock_gettime
函数在 Linux 下由 node.js(libuv?)轮询,但在 Linux 下运行时不会调用此函数苹果系统。 (我在 libfaketime
函数中添加了一些 printf
)
导致 Mac OS 和 Linux 之间行为差异的 node.js(libuv?)的实现有何不同?为什么会存在这种实现差异?
我所做的另一个观察是,当使用 libfaketime
卡住时间时,setImmediate
和 setTimeout(cb, 0)
的行为在以下情况下有所不同Linux 在使用 setImmediate
时运行回调,但在使用 setTimeout(cb, 0)
时不运行。
最佳答案
绝对是libuv的区别。 Darwin 没有support CLOCK_MONOTONIC*
,因此 mach_absolute_time()
must be called为了得到当前时间。这最终会绕过 libfaketime
,导致客户端代码在 OS X 上实时运行。
关于node.js - 使用 libfaketime 时,setTimeout 在 Mac OS 和 Linux 上的行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50609978/