随机文件写作

时间:2016-05-10 21:04:49

标签: c++ multithreading c++11 memory-mapped-files system-design

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

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

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

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

如果fwrite可以是“随机”,那么输出编写器可以简单地获取输出,搜索,然后写入。但是不确定这种设计是否能够大规模地发挥作用。

一些限制

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

1 个答案:

答案 0 :(得分:1)

假设每个块的大小相同,并且在需要将块写入磁盘之前在内存中生成块,那么lseekwrite的组合将完全正常。< / p>

如果你能够在一次写入中编写整个块,那么使用fwrite就不会有任何好处 - 所以只需直接使用write - 但是如果所有线程都需要某种锁定访问控制(mutex)共享相同的fd - 因为seek + write不能以原子方式完成,并且你不希望一个线程在第二个线程即将写入之前寻找。

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

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