【发布时间】:2016-09-06 01:09:20
【问题描述】:
如果我有多个线程生成文件块,写出块的最佳方法是什么?
ex) 5 个线程处理 500 个块的文件,块 0 不一定在块 1 之前完成,但磁盘上的输出文件需要按顺序排列。 (区块 0,区块 1,区块 2,……区块 499)
程序是 C++,fwrite() 能以某种方式“随机访问”文件吗?该文件是从头开始创建的,这意味着当块 5 完成时,由于块 1~4 尚未完成,文件可能仍为 0 大小。我可以直接写出第5块吗? (使用适当的 fseek)
这段代码对性能至关重要,所以我真的很好奇任何可以提高性能的东西。这看起来像一个多生产者(块生成器)和一个消费者(输出写入器)场景。思路案例是线程A完成前一个块后可以继续生成下一个块。
如果 fwrite 可以是“随机的”,那么输出写入器可以简单地获取输出,查找,然后写入。但是不确定这种设计是否可以大规模执行。
一些限制
- 每个块大小相同,在内存中生成
- 块大小是预先知道的,但不是块的总数。
- 总大小为几 GB。很大。
- 可能有多个作业在一台服务器上运行。每个工作都在上面进行了描述。他们有自己独立的生成器/写入器,不同的进程。
- 服务器是 Linux/CentOS 机器。
【问题讨论】:
-
块的大小都一样吗?
-
为什么不在内存中组装文件并在完成后将其打印到磁盘?
-
fseek你会找到的(尽管你可能希望在搜索之前积累至少几千字节的连续数据)。 -
你应该能够 fseek + fwrite (如果你想并行化它,你可能需要原子地执行这两个调用),但在你这样做之前将文件扩展到所需的大小。这是假设事先知道文件的最终大小。 :)
-
无法帮助您使用 Linux,但我发现标准库比 OS API 更慢且更不灵活。显然,你牺牲了便携性。我建议阅读 Linux API 提供的内容并尝试一下。内存映射文件可能是一种简单且高效的解决方案。
标签: c++ multithreading c++11 memory-mapped-files system-design