Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Node.js process.exit()不能干净地退出,异步fs.writeFile的危险 tl;医生:_Javascript_Node.js_File - Fatal编程技术网

Javascript Node.js process.exit()不能干净地退出,异步fs.writeFile的危险 tl;医生:

Javascript Node.js process.exit()不能干净地退出,异步fs.writeFile的危险 tl;医生:,javascript,node.js,file,Javascript,Node.js,File,从异步事件调用异步fs.writeFile(甚至可能只是从一个普通的旧循环),然后调用process.exit()成功打开文件,但无法将数据刷新到文件中。给writeFile的回调在进程退出之前没有机会运行。这是预期的行为吗 无论process.exit()是否无法执行此清理,我都会质疑节点是否有责任至少尝试将文件写入计划,因为很可能是这样的情况:大型缓冲区的释放取决于将它们写入磁盘 细节 我有一段node.js代码,它在一个大数据文件上执行转换。这恰好是一个激光雷达传感器的数据文件,不应该是相

从异步事件调用异步
fs.writeFile
(甚至可能只是从一个普通的旧循环),然后调用
process.exit()
成功打开文件,但无法将数据刷新到文件中。给
writeFile
的回调在进程退出之前没有机会运行。这是预期的行为吗

无论
process.exit()
是否无法执行此清理,我都会质疑节点是否有责任至少尝试将文件写入计划,因为很可能是这样的情况:大型缓冲区的释放取决于将它们写入磁盘

细节 我有一段node.js代码,它在一个大数据文件上执行转换。这恰好是一个激光雷达传感器的数据文件,不应该是相关的。由于其存在的性质,它只是一个相当大的数据集。它结构简单。传感器通过网络发送数据。这个脚本的任务是为每个旋转扫描生成一个单独的文件。这种逻辑的细节也无关紧要

基本思想是使用node_pcap读取一个巨大的
.pcap
文件,使用node_pcap执行此任务的方法,即“脱机模式”

这意味着不是异步捕获网络数据包,而是“生成”表示数据包的相当密集的异步事件流

因此,程序的主要结构由几个全局状态变量和对pcap会话的单个回调组成。我初始化globals,然后将回调函数分配给pcap会话。对
数据包
事件的回调完成了所有工作

这项工作的一部分是写出大量的数据文件。每隔一段时间,一个数据包会指示一些条件,这意味着我应该继续写入下一个数据文件。我增加数据文件名索引,然后再次调用
fs.writeFile()
开始写入新文件。因为我只是在写作,所以让node决定什么时候开始写作似乎很自然

基本上,
fs.writeFileSync
fs.writeFile
都应该以异步方式调用操作系统对各自文件的
write()
系统调用。这并不困扰我,因为我只是在写,所以写的异步性质对我来说并不重要,因为我不做任何访问,它会影响某些访问模式。唯一的区别在于
writeFileSync
强制节点事件循环阻塞,直到
write()
syscall完成

随着程序的进行,当我使用
writeFile
(js异步版本)时,会创建数百个输出文件,但不会向它们写入任何数据。一个也没有。创建第一百个数据文件时,第一个数据文件仍处于打开状态

这在概念上是好的。原因是node正忙于处理新数据,并且很高兴地保留着越来越多的文件描述符,以便将文件的数据写入其中。同时,它还必须将文件的所有最终内容保存在内存中。这将最终耗尽,但让我们暂时忽略RAM大小限制。显然,这里发生的一件坏事是内存不足,程序崩溃。希望节点会很智能,并意识到它只需要安排一些文件写入,然后它就可以释放一堆缓冲区

如果我在所有这些中间插入一个语句来调用<代码>进程。()/代码>,我希望节点在退出之前将清理并刷新未决的<代码>写文件< /COD>写。p> 但node不这样做

更改为
writeFileSync
显然解决了这个问题。 更改和截断我的输入数据,以便不显式调用
process.exit()
,也会导致文件最终在输入事件结束时被写入(以及执行给
writeFile
的完成回调)

对我来说,这似乎表明
process.exit()
不正确地执行了清理

<强>问题:中间有没有退出事件循环的替代方案?注意:我必须手动截断我的大输入文件,因为使用

process.exit()
终止会导致所有文件写入未完成

这是node
v0.10.26
不久前用自制软件安装在OS X上

继续我的思考过程,我在这里看到的行为对使用
writeFile
的基本目的提出了质疑。它应该能够改进一些事情,以便在node认为合适的时候灵活地编写我的文件。然而,很明显,若节点的事件循环被泵入足够大的压力,那个么它基本上会在工作负载上“落后”

这就像事件循环有一个收件箱和一个发件箱。在这个类比中,发件箱表示包含我正在写入文件的数据的临时变量。像我这样一个懒惰而多产的程序员想要做的假设是,收件箱和发件箱是我可以使用的接口,它们是灵活的,系统将为我管理。但是,如果我以过高的速率向收件箱发送数据,那么node实际上无法跟上,它只会开始将数据堆积到发件箱中,而没有时间刷新它,因为出于这样或那样的原因,调度是这样的,所有传入的事件都必须首先得到处理。这反过来会延迟发件箱内容的所有垃圾收集,并且很快就会耗尽系统的RAM。当这个模式在复杂的应用程序中使用时,这很容易成为一个很难发现的bug