随机文件写入
Random File Writing
如果我有多个线程生成文件块,写出块的最佳方法是什么?
ex) 5 个线程处理一个包含 500 个块的文件,块 0 不一定在块 1 之前完成,但磁盘上的输出文件需要有序。 (第 0 块,第 1 块,第 2 块,....第 499 块)
该程序是用 C++ 编写的,可以 fwrite() 以某种方式 "random access" 文件吗?该文件是从头开始创建的,这意味着当块 5 完成时,由于块 1~4 尚未完成,文件的大小可能仍为 0。我可以直接写出块5吗? (使用适当的 fseek)
这段代码对性能至关重要,所以我真的很好奇任何可以提高性能的东西。这看起来像是多个生产者(块生成器)和一个消费者(输出编写器)的场景。理想情况是线程A可以在完成前一个块后继续生成下一个块。
如果 fwrite 可以是 "random",那么输出写入器可以简单地获取输出、查找,然后写入。但是不确定这种设计是否可以在大规模上表现良好。
一些限制
- 每个块大小相同,在内存中生成
- 块大小是预先知道的,但不是块的总数。
- 总大小为几 GB。大.
- 一台服务器上可以有多个作业运行。每项工作都在上面进行了描述。他们有自己独立的generators/writer,不同的进程。
- 服务器是 Linux/CentOS 机器。
假设每个块大小相同,并且块在需要写入磁盘之前在内存中生成,那么 lseek
和 write
的组合就完美了.
如果您能够在一次写入中写入整个块,那么使用 fwrite 将不会获得任何优势——所以只需直接使用 write——但是,如果全部,您将需要某种锁定访问控制(互斥锁)线程共享相同的 fd——因为 seek+write 不能以原子方式完成,并且您不希望一个线程在第二个线程即将写入之前进行搜索。
这进一步假设您的文件系统是标准文件系统,而不是一些奇特的文件系统,因为并非所有 input/output 设备都支持 lseek
(例如管道)。
更新:lseek可以越过文件尾查找,只需要设置whence参数=SEEK_SET和偏移到文件中的绝对位置(fseek有相同的选项,但我没用过) .
如果我有多个线程生成文件块,写出块的最佳方法是什么?
ex) 5 个线程处理一个包含 500 个块的文件,块 0 不一定在块 1 之前完成,但磁盘上的输出文件需要有序。 (第 0 块,第 1 块,第 2 块,....第 499 块)
该程序是用 C++ 编写的,可以 fwrite() 以某种方式 "random access" 文件吗?该文件是从头开始创建的,这意味着当块 5 完成时,由于块 1~4 尚未完成,文件的大小可能仍为 0。我可以直接写出块5吗? (使用适当的 fseek)
这段代码对性能至关重要,所以我真的很好奇任何可以提高性能的东西。这看起来像是多个生产者(块生成器)和一个消费者(输出编写器)的场景。理想情况是线程A可以在完成前一个块后继续生成下一个块。
如果 fwrite 可以是 "random",那么输出写入器可以简单地获取输出、查找,然后写入。但是不确定这种设计是否可以在大规模上表现良好。
一些限制
- 每个块大小相同,在内存中生成
- 块大小是预先知道的,但不是块的总数。
- 总大小为几 GB。大.
- 一台服务器上可以有多个作业运行。每项工作都在上面进行了描述。他们有自己独立的generators/writer,不同的进程。
- 服务器是 Linux/CentOS 机器。
假设每个块大小相同,并且块在需要写入磁盘之前在内存中生成,那么 lseek
和 write
的组合就完美了.
如果您能够在一次写入中写入整个块,那么使用 fwrite 将不会获得任何优势——所以只需直接使用 write——但是,如果全部,您将需要某种锁定访问控制(互斥锁)线程共享相同的 fd——因为 seek+write 不能以原子方式完成,并且您不希望一个线程在第二个线程即将写入之前进行搜索。
这进一步假设您的文件系统是标准文件系统,而不是一些奇特的文件系统,因为并非所有 input/output 设备都支持 lseek
(例如管道)。
更新:lseek可以越过文件尾查找,只需要设置whence参数=SEEK_SET和偏移到文件中的绝对位置(fseek有相同的选项,但我没用过) .