测试缓冲区是不是已在 R 中刷新

Posted

技术标签:

【中文标题】测试缓冲区是不是已在 R 中刷新【英文标题】:Testing whether buffers have been flushed in R测试缓冲区是否已在 R 中刷新 【发布时间】:2011-08-08 21:56:09 【问题描述】:

我有一些非常大的文件要处理,我使用几个不同的 I/O 函数来访问它们。最常见的是bigmemory 包。

在写入文件时,我已经学会了刷新输出缓冲区的艰难方法,否则所有关于数据是否已保存的赌注都将落空。但是,这可能会导致在bigmemory 完成它的工作(很多分钟)时等待一些非常长的时间。我不知道为什么会发生这种情况——它并不总是发生,也不容易重现。

是否有某种方法可以确定 I/O 缓冲区是否已在 R 中刷新,尤其是对于 bigmemory?如果操作系统很重要,请随意以这种方式限制答案。

如果可以将答案推广到 bigmemory 之外,那就太好了,因为我有时会依赖其他内存映射函数或 I/O 流。

如果没有好的解决方案来检查缓冲区是否已被刷新,是否存在可以假设缓冲区已被刷新的情况? IE。除了使用flush()

更新:我应该澄清一下,这些都是二进制连接。 @RichieCotton 注意到 isIncomplete(),尽管帮助文档只提到了文本连接。不清楚这是否可用于二进制连接。

【问题讨论】:

不确定是否与bigmemory 一起使用,但isIncomplete 适用于常规连接。 谢谢!关于连接的非常有限的帮助信息只提到 isIncomplete 适用于文本连接的输出。你在二进制连接上遇到过运气吗? 【参考方案1】:

isIncomplete() 处理二进制文件是否更有说服力?

# R process 1
zz <- file("~/test", "wb")
writeBin(c(1:100000),con=zz)
close(zz)

# R process 2
zz2 <- file("~/test", "rb")
inpp <- readBin(con=zz2, integer(), 10000)
while(isIncomplete(con2)) Sys.sleep(1); inpp <- c(inpp, readBin(zz2),integer(), 10000)
close(zz2)

(根据帮助(连接)文件修改。)

【讨论】:

感谢您对此进行测试。但是,除非我误读了,否则您的示例仅在输入缓冲区的情况下使用它。我不太清楚它是否适用于输出缓冲区。我对输出缓冲不够熟悉,无法确定我们是否可以以同样的方式对其进行测试。我只是不愿意超越文档-如果它的行为是随机的,而不是确定性的,那么我冒着一堆损坏的数据的风​​险。我一直在这条路上,所以我很谨慎。 :) 经过进一步测试,我认为isIncomplete() 不适用于bigmemory 对象:似乎对象是某种指针,而不是连接。 :( 感谢您的建议和示例。事实证明,在这种情况下,缓冲区是在 R 之外处理的。【参考方案2】:

我会提出我自己的答案,但我欢迎任何更清楚的内容。

据我目前所见,各种连接功能,例如fileopencloseflushisOpenisIncomplete(以及其他)基于特定的连接类型,例如文件、管道、URL 和其他一些东西。

相比之下,bigmemory 有自己的连接类型,而 bigmemory 对象是一个 S4 对象,带有一个用于操作系统缓冲区的内存地址的插槽。一旦放置在那里,操作系统就负责刷新这些缓冲区。由于这是操作系统的责任,因此获取有关“脏”缓冲区的信息需要与操作系统交互,而不是与 R。

因此,bigmemory 的答案是“否”,因为数据存储在内核缓冲区中,尽管对于通过 STDIO 处理的其他连接(即存储在“用户空间”中)可能是“是”。

有关操作系统/内核方面的更多信息,请参阅this question on SO;我正在研究几个产生缓冲区刷新好奇心的程序(不仅仅是 R + bigmemory),该线程帮助我了解了内核方面的事情。

【讨论】:

以上是关于测试缓冲区是不是已在 R 中刷新的主要内容,如果未能解决你的问题,请参考以下文章

用于多线程的 NAudio:缓冲区已在播放错误时排队

printf缓冲区刷新问题

了解 netty 通道缓冲区和水印

Python 文件操作

C 语言文件操作 ( fflush 函数 | 刷新缓冲区示例代码 )

DatagramPacket - getData 是不是总是返回传递的相同缓冲区?