4

如果我有多个线程生成文件块,写出块的最佳方法是什么?

ex) 5 个线程处理 500 个块的文件,块 0 不一定在块 1 之前完成,但磁盘上的输出文件需要按顺序排列。(块 0,块 1,块 2,......块 499)

该程序是 C++ 中的,fwrite() 可以以某种方式“随机访问”文件吗?该文件是从头开始创建的,这意味着当块 5 完成时,由于块 1~4 尚未完成,文件可能仍为 0 大小。我可以直接写出第5块吗?(使用适当的 fseek)

这段代码对性能至关重要,所以我真的很好奇任何可以提高性能的东西。这看起来像一个多生产者(块生成器)和一个消费者(输出写入器)场景。想法案例是线程A在完成前一个块时可以继续生成下一个块。

如果 fwrite 可以是“随机的”,那么输出写入器可以简单地获取输出,查找,然后写入。但是不确定这种设计是否可以大规模执行。

一些限制

  • 每个块大小相同,在内存中生成
  • 块大小是预先知道的,但不是块的总数。
  • 总大小为几 GB。大的。
  • 一台服务器上可能运行多个作业。每个工作都在上面进行了描述。他们有自己独立的生成器/编写器,不同的进程。
  • 服务器是 Linux/CentOS 机器。
4

1 回答 1

1

假设每个块的大小相同,并且这些块是在需要将它们写入磁盘之前在内存中生成的,那么lseek和的组合write就可以了。

如果您能够在一次写入中写入整个块,则使用 fwrite 不会获得任何优势 - 所以只需直接使用 write - 但是如果所有线程都共享,您将需要某种锁定访问控制(互斥锁)相同的 fd - 因为 seek+write 不能原子地完成,并且您不希望一个线程在第二个线程即将写入之前搜索。

这进一步假设您的文件系统是标准文件系统,而不是某种奇异的性质,因为并非所有输入/输出设备都支持lseek(例如管道)。

更新: lseek 可以在文件末尾之外进行查找,只需将 whence 参数 = SEEK_SET 和偏移量设置为文件中的绝对位置(fseek 具有相同的选项,但我从未使用过)。

于 2016-05-10T21:13:47.073 回答