console.log是原子的吗?

3
Python中的print语句不是线程安全的。在Node.js中同时使用console.log是否安全?
如果是,那么它是否也是交错安全的?也就是说,如果多个(甚至数百个)回调写入控制台,我可以确定输出不会被破坏或交错吗?
查看源代码,似乎Node.js会将并发尝试写入流排队(这里)。另一方面,console.log替换标志来自printf(3)。如果console.log包装printf,那么它可能会在POSIX机器上交错输出(如此示例所示)。
请在回答这个问题时告诉我在 Node.js 中 async ._write(chunk, encoding, cb) 实现的位置。
编辑:如果同时向流中写入数据是可以的,那么为什么会有这个npm包存在?

Node.js是单线程的。回调可能来自不同的线程,但一旦它们进入主线程,就没有并发操作了。 - 4castle
3个回答

4

在Node.js中,所有操作基本上都是"原子性"的。这是因为Node.js是单线程的——没有代码可以被打断。


3
是的,任何时候只有其中一个会被执行,但是所有的2000个线程都可以并行地等待。这就是并发的含义 - 代码可以在并行等待而不执行。并发不等于并行。 - slebetman
好的,但是“原子性”的写入是按字符还是按换行符?另外,请查看我在你回答这个问题之后所做的编辑。我理论上明白你的意思,但我需要更深入的解释。 - Coder
@andrerpena:这里有两个我之前写的解释架构的答案链接:https://dev59.com/cXjZa4cB1Zd3GeqPeHE3#19620041,https://dev59.com/Kl0a5IYBdhLWcg3w07zt#29885509。 - slebetman
@程序员:不,原子性指的是console.log()函数本身的执行,包括对printf()等内部调用。在JavaScript中,没有任何函数直接写入标准输出流(stdout)。相反,它将写入操作排队到事件循环中(即你找到的代码)。因此,“原子性”通过“消息”来进行写入。 - slebetman
@程序员:请注意,node.js使用一个线程来处理所有事情:控制台、套接字等。唯一的例外是磁盘I/O,此时node会为每个文件使用一个线程,这仍然意味着I/O在技术上是线程安全的。 - slebetman
显示剩余4条评论

1

0

根据我在Node.js控制台上看到的,它并不是“交错安全”的。

我可以看到我的控制台输出有时会被“覆盖或交错”。并非总是如此。当我运行程序时,可能每5次才会看到来自多个日志语句的交错输出。

这当然可能取决于您的Node.js版本和正在运行它的操作系统。记录一下,我的Node.js版本是v12.13.0,操作系统是Windows 10.0.19042。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接