我有一个名为foo.txt
的文件,其中有一行
我想对产生10个新行的每一行应用一个操作。预计输出约为10B行
为了提高速度和IO,foo.txt
位于DiskA和bar.txt
DiskB上(物理上说是不同的驱动器)
DiskB将成为限制因素。因为有很多行要写,所以我在写入DiskB时添加了一个大的缓冲区
我的问题是:当我在diskB上调用flush()时,文件处理程序的缓冲区会将其刷新到硬盘上。这似乎是一个非阻塞调用,因为命令返回,但我仍然可以看到磁盘正在写入,其忙指示灯为100%。几秒钟后,指示灯返回到0%。python中有没有一种方法可以等待磁盘完成?理想情况下,我希望flush()是一个阻塞调用。我现在看到的唯一解决方案是添加任意sleep(),并希望磁盘准备就绪
下面是一个可视的片段(实际上有点复杂,因为bar.txt
不仅仅是一个文件,而是数千个文件,因此IO效率非常低):
with open('bar.txt', 'w', buffering=100 * io.DEFAULT_BUFFER_SIZE) as w:
with open('foo.txt') as r:
for line in r:
# writes each line of foo 10 times in bar.
for i in range(10):
w.write(line)
# w.flush()
我认为有几个问题
"when the disk is ready"
的定义必须非常清楚李>根据操作系统、文件系统和操作系统/文件系统配置的不同,要知道数据何时写入磁盘将有不同的答案
请注意,以下情况不相同(或可能不相同):
主要的问题是,为什么你必须知道最后一个字节是什么时候写的
如果您的动机是性能,那么也许只有两个线程就足够了:
threading.Queue
),队列中的条目数最大。这意味着,当队列达到一定大小时,读取/处理线程将被阻塞如果上述情况是这样的,并且您从未使用过
threading
和threading Queue
,我可以增强我的回答。告诉我然而,如果你说,书写/刷新不是/从不阻塞,那么 这没用
为了好玩,您可以实现上述线程,并定期使用第三个线程检查队列的大小,以确定写入是否真的是瓶颈。如果是的话,那么你的FIFO大部分时间都应该(几乎)满了
第一次反馈后的评论:
您正在linux上运行一个SSD驱动器,其中包含要写入的ext4
看起来,但我仍然不确定,一个比问题中更具代表性的例子是,一个脚本只是以不同的数据速率交替写入N个文件
我仍然有这样的印象,增加写缓冲区大小并让操作系统完成其余的工作应该会给您带来性能,而手动干预很难提高性能
不过,禁用磁盘日志记录可能会提高性能
这个模型会解决你的问题吗?(我知道在现实中,作家的写作速度并不是恒定的,作家写作的顺序也是随机的)
我觉得我错过了什么。 为什么这些潮水会加速任何事情? 这是一个SSD。它没有任何机械延迟等待,磁盘旋转到某个地方。只有在“有足够值得写入的数据”的情况下,缓冲才会写入文件
我还感到困惑的是,你说
flush()
是非阻塞的缓冲写入只是将数据放入缓冲区,并在缓冲区已满时调用flush(),这意味着write()也是非阻塞的
如果一切都是非阻塞的,那么您的进程将失去0个编写时间,并且不会有任何需要优化的内容
所以我想,write()和flush()是阻塞调用,但不是以您希望它们阻塞的方式阻塞调用。在操作系统接受数据进行写入之前,它们可能一直处于阻塞状态(这并不意味着数据已经写入) 只要操作系统决定这样做,就会发生对磁盘的真正写入。 由于存在写入缓存,磁盘控制器可能会添加一些其他层的写入缓存/写入重新排序
为了检查这一点,您可以在以下类型的每次写入中添加调试代码
您可能会有一个t_max,这表明。write是阻塞的 ....
相关问题 更多 >
编程相关推荐