从两个不同的 Worker 线程调用的 console.log() 是否可以相互踩踏,或者它们总是一个接一个?
Can console.log()s called from two different Worker threads ever step on each other, or are they always one after the other?
我有一小段示例代码:
//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.[= 中不那样工作16=]
console.log()
对于基元(非对象)是线程安全的。因此,在您传递字符串的特定示例中,这是安全的,您不会混淆输出。
但是,如果您将一个对象传递给 console.log(obj)
并且线程正在修改该对象,那么在将对象转换为输出并编组到日志输出之前可能会出现问题。这甚至可能只发生在一个线程中,您可以在其中立即修改后续代码行中的对象。
这显然是因为对象到控制台输出的转换是“惰性的”而不是即时的。这可能是为了尽量减少调用 console.log()
对性能的影响而并行 运行 的尝试。我在实际代码中看到过这一点,解决方法是调用 console.log(JSON.stringify(obj))
而不是 console.log(obj)
来消除对象在延迟记录之前被修改的任何问题。
我有一小段示例代码:
//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.[= 中不那样工作16=]
console.log()
对于基元(非对象)是线程安全的。因此,在您传递字符串的特定示例中,这是安全的,您不会混淆输出。
但是,如果您将一个对象传递给 console.log(obj)
并且线程正在修改该对象,那么在将对象转换为输出并编组到日志输出之前可能会出现问题。这甚至可能只发生在一个线程中,您可以在其中立即修改后续代码行中的对象。
这显然是因为对象到控制台输出的转换是“惰性的”而不是即时的。这可能是为了尽量减少调用 console.log()
对性能的影响而并行 运行 的尝试。我在实际代码中看到过这一点,解决方法是调用 console.log(JSON.stringify(obj))
而不是 console.log(obj)
来消除对象在延迟记录之前被修改的任何问题。