是否可以从多个线程写入同一文件的不同部分?
Posted
技术标签:
【中文标题】是否可以从多个线程写入同一文件的不同部分?【英文标题】:Is is possible to write to different parts of the same file from multiple threads? 【发布时间】:2013-03-06 20:30:25 【问题描述】:我可以从多个线程(在典型的 PC 上)同时写入同一文件的不同部分吗?我的意思是只有一个磁头,所以写入只能以某种顺序执行,即不能并行,对吧?
编辑:
我正在编写一个对大型二进制文件进行排序的程序,但大部分时间仍然花在磁盘 I/O 上,所以我只是想知道通过并行 I/O 是否会获得额外的速度。
【问题讨论】:
是的,这应该是可能的,这就是 utorrent 软件的工作原理..!! 您说的是物理并行性?如果您谈论物理并行性 - 想想它如何与单核处理器一起工作。 它不会解决你的 IO 问题。如果您最终需要从不同线程写入同一个文件以解决 CPU 绑定限制,它会起作用,但不会提高您的 IO 速度。如果有的话,它会稍微减少。 【参考方案1】:没有什么可以阻止您让多个线程写入同一文件的不同部分。
我有一个对大型二进制文件进行排序的程序,但大部分时间仍然花在磁盘 I/O 上,所以我只是想知道通过并行执行 I/O 是否会获得额外的速度。
如果程序是磁盘绑定的,使其成为多线程(并且仍然将相同数量的数据写入同一个磁盘)不会加快它的速度。
如果我们谈论的是传统硬盘驱动器,顺序 I/O 通常比涉及来回移动磁盘磁头的 I/O 更快。考虑到这一点,跨线程拆分 I/O 甚至可能适得其反。
就加快速度而言,有多种途径可供探索:
-
减少 I/O 量(例如,通过采用需要更少 I/O 的排序算法,或通过在内存中执行更多工作);
提高 I/O 吞吐量,例如使用更快的驱动器。
【讨论】:
【参考方案2】:至少在 unix(-like) 操作系统上是可能的,大概在 Windows 上也是可能的,尽管文件处理有些不同,可能需要特定的文件模式允许这样做(编辑:参见 answer of bizzehdee 了解详细信息)。
在运行的操作系统上,“文件”实际上是一个逻辑实体,它的某些状态在任何给定时间都存储到磁盘中,但也有一些变化仅在内核缓冲区中。因此,在某种程度上,写入文件与写入共享内存块没有什么不同,只是 API 不同(即使使用 mmap
也不一样)。
但简而言之,只要查找和写入,文件中的旧字节就会被覆盖。如果两个进程在相同的字节上重叠写入,我认为最终结果是未定义的,并且在任何情况下都不应该在正常运行的系统中发生,并且任何这样做的程序都应该有一些机制来防止重叠写入。
关于加速:真的取决于你做什么。如果您只执行原始写入,传统旋转硬盘的速度可能会变慢,或者文件可能更容易碎片化。在 SSD 上,可能没有减速,但也没有加速。
另一方面,如果您的操作是 CPU 密集型的,并且您有多个内核,并且并行处理可以让您获得更高的总 CPU 使用率,那么并行处理同一输出文件的不同部分可以加快速度事情,如果与写入文件的字节相比有很多处理,甚至很多。
【讨论】:
【参考方案3】:您需要查看CreateFileEx
和WriteFileEx
并使用lpOverlapped
。这允许在多个线程中同时异步读取和/或写入同一文件。
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365748(v=vs.85).aspx
【讨论】:
【参考方案4】:是的,这是可能的,但正如其他人所说,在一般情况下,最不太可能提高性能。
但是,您的其中一个陈述并不正确。
只有一个磁头
首先,通常每个表面都有一个,因此即使是单盘 HDD 也会有两个磁头。当然,多盘的有更多。
一些具有多个盘片的驱动器也能够同时读取或写入所有盘片。 80 年代的一些Fujitsu Eagle drives 做到了这一点,并被用于第一批能够记录未压缩数字视频信号的系统。当然,这不是“随机访问”,因为所有头都一起移动。我不确定现代驱动器是否使用这种技术。
【讨论】:
以上是关于是否可以从多个线程写入同一文件的不同部分?的主要内容,如果未能解决你的问题,请参考以下文章
使用来自多个进程的 fseek/fwrite 写入文件的不同区域?