使用 libfaketime 时,setTimeout 在 Mac OS 和 Linux 上的行为不同
setTimeout behaves differently on Mac OS and Linux when using libfaketime
当使用libfaketime
改变进程的时间速度时,setTimout
设置的超时根据运行ning在Linux下改变的时间到期但是根据MacOS.
下运行ning时的原系统时间
在Mac OS:
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?) 轮询,但是当运行宁下 Mac OS。 (我在 libfaketime
函数中添加了一些 printf
s)
导致 Mac OS 和 Linux 之间行为差异的 node.js(libuv?)的实施有何不同?为什么会存在这种实施差异?
我的另一个观察是,当使用 libfaketime
冻结时间时,setImmediate
和 setTimeout(cb, 0)
的行为在 Linux 下有所不同,因为回调是 运行 在使用 setImmediate
时使用 setTimeout(cb, 0)
.
绝对是libuv的区别。达尔文不会support CLOCK_MONOTONIC*
, therefore mach_absolute_time()
must be called为了得到当前时间。这最终会绕过 libfaketime
,导致客户端代码在 OS X 上实时 运行。
当使用libfaketime
改变进程的时间速度时,setTimout
设置的超时根据运行ning在Linux下改变的时间到期但是根据MacOS.
在Mac OS:
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?) 轮询,但是当运行宁下 Mac OS。 (我在 libfaketime
函数中添加了一些 printf
s)
导致 Mac OS 和 Linux 之间行为差异的 node.js(libuv?)的实施有何不同?为什么会存在这种实施差异?
我的另一个观察是,当使用 libfaketime
冻结时间时,setImmediate
和 setTimeout(cb, 0)
的行为在 Linux 下有所不同,因为回调是 运行 在使用 setImmediate
时使用 setTimeout(cb, 0)
.
绝对是libuv的区别。达尔文不会support CLOCK_MONOTONIC*
, therefore mach_absolute_time()
must be called为了得到当前时间。这最终会绕过 libfaketime
,导致客户端代码在 OS X 上实时 运行。