【问题标题】:Writing a large number of files from a long running process?从长时间运行的进程中写入大量文件?
【发布时间】:2012-09-06 21:23:03
【问题描述】:

我有一个项目,它扫描一个大文件 (2.5GB),挑选出字符串,然后将其写入数百个文件的某个子集。

使用普通缓冲写入会是最快的,但是

  1. 我担心文件句柄用完。
  2. 我希望能够在文件写入时查看它们的进度。
  3. 如果进程中断,我希望损失尽可能少。不完整的文件仍有部分用途。

所以我改为以读/写模式打开,添加新行,然后再次关闭。

这在很多时候已经足够快了,但我发现在某些操作系统上这种行为是一种严重的悲观。上次我在 Windows 7 上网本上运行它时,我在几天后中断了它!

我可以实现某种类型的 MRU 文件句柄管理器,它可以保持如此多的文件打开并在每个文件进行如此多的写入操作后刷新。但这是否矫枉过正?

这一定是常见的情况,有没有“最佳实践”、“模式”?

当前的实现是在 Perl 中,并且已经在 Linux、Solaris 和 Windows、上网本到 phat 服务器上运行。但我对一般问题感兴趣:语言无关和跨平台。我曾想过用 C 或 node.js 编写下一个版本。

【问题讨论】:

  • 你是如何读取文件的?逐行?立刻? 2.5 没那么大。
  • 我逐条阅读它,但这归结为逐行。似乎输入的大小并没有像我认为的输出的所有刷新一样减慢它的速度。
  • 到目前为止我能找到的最相似的问题:Opening and writing to multiple files in C

标签: optimization io output-buffering filehandle


【解决方案1】:

在 Linux 上,您可以打开很多文件(数千个)。您可以使用setrlimit 系统调用和ulimit shell 内置函数来限制单个进程中打开的句柄数。您可以使用getrlimit 系统调用查询它们,也可以使用/proc/self/limits(或/proc/1234/limits 用于pid 1234 的进程)。系统范围内打开文件的最大数量是 /proc/sys/fs/file-max(在我的系统上,我有 1623114)。

所以在 Linux 上,您不必费心,一次打开许多文件。

我建议维护一个memoizedcache 打开的文件,并尽可能使用它们(在 MRU 策略中)。不要过于频繁地打开和关闭每个文件,只有在达到某个限制时...(例如,当 open 确实失败时)。

换句话说,你可以有自己的文件抽象(或只是一个struct),它知道文件名,可能有一个打开的FILE*(或一个空指针)并保持当前的偏移量,也许还有最后一次打开或写入,然后在 FIFO 规则中管理这些东西的集合(对于那些打开 FILE* 的人)。您当然希望避免close-ing(以及后来重新open-ing)文件描述符过于频繁。

您可能偶尔(即几分钟一次)致电sync(2),但不要太频繁(当然每 10 秒不超过一次)。如果使用缓冲的FILE-s 不要忘记有时fflush 他们。同样,不要经常这样做。

【讨论】:

  • 我打开、追加、刷新和关闭文件数百万次的方式在 Linux 上是否会成为问题?我似乎记得读过最近在 Linux 中的优化使这变得很糟糕,我认为这与 Firefox 如何编写它使用的某些类型的文件以及像我一样的持续刷新有关。
  • 我不熟悉 memoized 缓存的概念 - 这是我可以轻松实现跨平台的东西(Solaris 和 Windows 是其他环境)。对于编程语言我也是开放的。
  • 我刚刚添加了关于记忆和缓存的维基百科链接
猜你喜欢
  • 2015-08-20
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多