使用cat命令合并多个线程创建的文件是否有效

Is using cat command to merge files created by multiple threads efficient?

本文关键字:创建 文件 是否 有效 线程 cat 命令 合并 使用      更新时间:2023-10-16

我有一个多线程c++ 11程序,其中每个线程产生大量需要写入磁盘的数据。所有的数据都需要写入一个文件。目前,我使用互斥锁来保护多个线程对文件的访问。我的朋友建议我,我可以为每个线程使用一个文件,然后在最后用cat命令将这些文件合并成一个文件,从c++代码中使用system()完成。
我在想,如果cat命令将从磁盘读取所有数据,然后将其再次写入磁盘,但这一次写入单个文件,它不会更好。我在谷歌上搜索过,但找不到cat命令实现细节。我可以知道它是如何工作的吗?它是否会加快整个过程?

编辑:

事件的时间顺序并不重要,并且对文件的内容没有排序约束。

您不指定是否对文件的内容有一些排序或结构约束。一般情况下是这样的,所以我将这样对待它,但希望我的解决方案在任何一种情况下都有效。

经典的编程方法

这个想法是将写入磁盘的工作卸载到一个专用的IO线程,并有多个生产者/一个消费者队列来排队所有写命令。每个工作线程只是将其输出格式化为字符串并将其推回队列。IO线程将队列中的消息批量弹出到缓冲区中,并发出写命令。

或者,你可以在你的消息中添加一个字段来指示哪个worker发出写命令,如果需要,让IO线程推送到不同的文件。

为了获得更好的性能,如果您的主机操作系统支持异步版本的IO系统原语(读/写),这也很有趣。IO线程将能够监视多个并发IO,并在一个IO终止时向OS提供新的IO。

正如在注释中建议的那样,您必须监视IO线程的拥塞情况,并相应地调整工作线程的数量。基于"自然"反馈的机制是简单地使队列有界,工人将等待锁,直到空间释放。这使您可以在进程生命周期的任何时刻控制生成的数据量,这在内存受限的场景中是一个重要的点。

您的cat关注

对于cat,这个命令行工具只是读取写入其输入通道(通常是stdin)的任何内容,并将其复制到其输出通道(stdout)。就这么简单,你可以清楚地看到它与上面所提倡的解决方案的相似之处。不同之处在于cat不理解文件内部结构(如果有的话),它只处理字节流,这意味着如果几个进程并发地写一个cat输入而没有同步,那么产生的输出可能会完全混淆。另一个问题是IO原语的原子性(或缺乏原子性)。


注意:在一些系统上,有一个叫做fork的小特性,它可以让你在一个文件中复用几个"独立"的数据流。如果你碰巧在一个支持该功能的平台上工作,你可以将所有数据流捆绑在一个文件中,但可以单独访问。