我正在尝试清除在Linux上运行的几个程序中使用不同语言的未刷新文件I / O缓冲区的问题。刷新缓冲区的解决方案很容易,但是这个未刷新的缓冲区问题是随机发生的。我不是在可能导致它的原因上寻求帮助,而是对如何创建(复制)和诊断这种情况感兴趣。
这导致了一个由两部分组成的问题:
人工和轻松地构造实例是否可行,在给定的时间段内,可以使用已知的输出缓冲区进行刷新?我的搜索结果是空的。一个简单的基线是在尝试从另一个进程写入大量数据的同时在一个进程中锤击硬盘驱动器(例如交换)。虽然这“有效”,但它使系统几乎无法使用:我不能四处寻找,看看发生了什么。
Linux中是否有命令可以识别给定进程是否有未刷新的文件输出缓冲区?这是可以在命令行运行的东西,还是需要直接查询内核?我一直关注fsync
,sync
,ioctl
,flush
,bdflush
等。但是,由于缺乏创建未刷新缓冲区的方法,目前尚不清楚这些缓冲区可能会发现什么。
为了重现他人,C中#1的例子非常好,但这个问题确实是语言不可知的 - 只要知道创建这种情况的方法就会有助于我正在使用的其他语言。 / p>
更新1:对于任何混淆我道歉。正如几位人士指出的那样,缓冲区可以位于内核空间或用户空间中。这有助于查明问题:我们正在创建大的脏内核缓冲区。这种区别和答案完全解决了#1:现在似乎很清楚如何在用户空间或内核空间中重新创建未刷新的缓冲区。但是,确定哪个进程ID具有脏内核缓冲区尚不清楚。
答案 0 :(得分:1)
一个具有未刷新缓冲区的简单程序将是:
main()
{
printf("moo");
pause();
}
Stdio,默认情况下,只有在连接到终端时才刷新换行符上的stdout。
答案 1 :(得分:1)
通过控制接收方很容易导致未刷新的缓冲区。 * nix系统的优点在于所有内容都看起来像文件,因此您可以使用特殊文件来执行您想要的操作。最简单的选择是管道。如果您只想控制标准输出,这是简单的选项:unflushed_program | slow_consumer
。否则,您可以使用命名管道:
mkfifo pipe_file
unflushed_program --output pipe_file
slow_consumer --input pipe_file
slow_consumer
很可能是您设计的用于缓慢读取数据的程序,或者只读取X字节并停止。
答案 2 :(得分:1)
如果您对内核缓冲数据感兴趣,那么您可以通过/proc/sys/vm/dirty_*
中的sysctls调整VM回写。特别是,dirty_expire_centisecs
是以百分之一秒为单位的年龄,脏数据有资格进行回写。增加此值将为您提供更大的调查时间窗口。您还可以增加dirty_ratio
和dirty_background_ratio
(这是系统内存的百分比,分别定义同步和异步写回的开始点)。
实际上创建脏页很容易 - 仅write(2)
到文件并退出而不同步,或者在文件的MAP_SHARED
映射中弄脏某些页面。