optimization - 从长时间运行的进程中写入大量文件?

标签 optimization io output-buffering filehandle

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

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

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

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

这在大部分时间都足够快,但我发现在某些操作系统上,这种行为是一种严重的悲观化。上次我在我的 Windows 7 上网本上运行它时,我在几天后中断了它!

我可以实现某种 MRU 文件句柄管理器,它可以让这么多文件保持打开状态,并在每次写操作之后刷新。但这是矫枉过正吗?

这一定是普遍情况,有没有“最佳实践”、“模式”?

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

最佳答案

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

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

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

换句话说,您可以有自己的文件抽象(或只是一个 struct),它知道文件名,可以有一个打开的 FILE*(或一个 null指针)并保持当前偏移量,也可能是上次打开或写入的时间,然后在 FIFO 规程中管理此类事物的集合(对于那些打开了 FILE* 的对象)。您当然希望避免过于频繁地close-ing(以及稍后重新open-ing)文件描述符。

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

关于optimization - 从长时间运行的进程中写入大量文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12308608/

相关文章:

javascript - 如何针对后台多个异步请求导致的延迟优化基于 Web 的应用程序?

c - 如何用C多次写入一个文件?

php - 将输出流式传输到文件和浏览器

PHP 输出缓冲——听起来不是个好主意,是吗?

php - 如何在 php 中设置输出缓冲区名称?

c++ - 查找与线段相交的所有图 block

python - 优化整数系数列表与其长整数表示之间的转换

java - 寻找一种更快的方法来执行字符串搜索

php - 如何并行读取多个文件?

haskell - 将 "yesod test"的所有输出发送到控制台