node.js - 使用 libfaketime 时,setTimeout 在 Mac OS 和 Linux 上的行为不同

标签 node.js linux macos settimeout libuv

当使用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?)轮询,但在 Linux 下运行时不会调用此函数苹果系统。 (我在 libfaketime 函数中添加了一些 printf)

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

我所做的另一个观察是,当使用 libfaketime 卡住时间时,setImmediatesetTimeout(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/

相关文章:

node.js - 从 node --inspect 命令打开 stdout 给出的 url

mysql - 如何在 mac 上卸载未使用的 MySQL 版本?

node.js - 图像不能是数组或对象 - sequelize、postgres、nodejs、multer

node.js - 如何从 Mongoose 查询结果中省略字段?

python - 为 Python 2.6 安装 Dropbox API 时遇到问题

linux - Grep 一个模式并打印文件头

linux - 无法使用新创建的帐户连接到 FTP

python - 如何在 Mac OS X 上安装 MySQLdb(Python 数据访问库到 MySQL)?

javascript - 发送指定 URL 的静态文件

node.js - Google OAuth2 服务帐户 HTTP/REST 身份验证