使用cat命令合并多个线程创建的文件是否有效
Is using cat command to merge files created by multiple threads efficient?
我有一个多线程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的小特性,它可以让你在一个文件中复用几个"独立"的数据流。如果你碰巧在一个支持该功能的平台上工作,你可以将所有数据流捆绑在一个文件中,但可以单独访问。
- 如何从Windows控制台调用.exe(C++)以在不同的目录(或任何目录)中创建文件夹?
- 避免使用 boost::进程间::消息队列创建文件
- 在C++中创建文件夹选取器对话框的最简单方法是什么?
- 如何在软件代码中使用ofstream创建文件
- 在特定 Unicode 路径中创建文件
- 两个线程一个使用流 Api,另一个线程创建文件失败并出现错误ERROR_SHARING_VIOLATION
- 即使使用 FILE_FLAG_DELETE_ON_CLOSE 属性创建文件,文件也会保留在磁盘上
- C++ 为每个结构{人}条目创建文件
- "Access is Denied" U盘上的创建文件()
- 在c++编程中的文件夹中创建文件
- 创建文件夹结构
- 在C++中创建文件夹
- 创建文件函数是否可以打开仅在WinObj实用程序中的全局目录下列出的设备的句柄?
- 使用 C++ 或 SDL 在 Android 中创建文件
- 如何检测哪些进程更改,重命名或创建文件?
- 如何在 Linux 中通过 C/C++ 以其他用户身份创建文件?
- 挂钩创建文件抛出异常:读取访问冲突
- UWP 创建文件2 ERROR_ACCESS_DENIED "NUL"
- 如何指定创建文件函数获取未缓存的结果?
- Open() 用于创建文件和打开现有文件.有人能分辨出其中的区别