【问题标题】:Can console.log()s called from two different Worker threads ever step on each other, or are they always one after the other?从两个不同的 Worker 线程调用的 console.log() 是否可以互相踩踏,或者它们总是一个接一个?
【发布时间】:2022-01-10 21:32:06
【问题描述】:

我有一小段示例代码:

//main.js

const {Worker} = require("worker_threads");

const worker = new Worker("./background.js", {workerData: {}});

function loop() {

    console.log("main: 1234567890");
    setTimeout(loop, 0)

}

loop();

还有:

//background.js

const {parentPort, workerData} = require("worker_threads");

function loop () {

    console.log("background: 1234567890");
    setTimeout(loop, 0)

}

loop();

像这样运行:node main.js

输出是这样的:

background: 1234567890
main: 1234567890
background: 1234567890
main: 1234567890
background: 1234567890
background: 1234567890
#etc

有时,一个线程中的多个console.log() 会在另一个线程调用之前被调用。这是意料之中的,很好。

但是有没有可能在另一个console.log() 的中间 调用console.log()?例如,这会发生吗?

background: 123main: 12345456786789090

我没有在我的输出中观察到它,但我想从规范的来源知道 Workers/console.log() 在 node.js 中不是这样工作的。

【问题讨论】:

    标签: javascript node.js ecmascript-6 web-worker


    【解决方案1】:

    console.log() 用于基元(非对象)是线程安全的。因此,在您传递字符串的特定示例中,这是安全的,您不会混淆输出。

    但是,如果您将一个对象传递给console.log(obj) 并且线程正在修改该对象,那么在该对象转换为输出并编组到日志输出之前可能会出现问题。这甚至可能发生在一个线程中,您可以立即在后续代码行中修改对象。

    这显然是因为对象到控制台输出的转换是“惰性的”而不是立即的。这可能是为了尽量减少调用console.log() 对性能的影响而尝试并行运行。我已经在实际代码中看到了这一点,解决方法是调用 console.log(JSON.stringify(obj)) 而不是 console.log(obj) 以消除在对象被延迟记录之前被修改的任何问题。

    【讨论】:

      猜你喜欢
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多