读取和写入硬盘的线程数是多少?

我正在开发一个应用程序,它收集硬盘驱动器的所有文件的列表,然后它会将文件写入硬盘驱动器。

我想问一下:执行此任务的最佳并发线程数是多少?

我的意思是我应该有多少线程读取硬盘驱动器而不会让硬盘驱动器变慢,因为很multithreading同时读取它。

谢谢 !

起初,我说一个!

它实际上取决于要读取的数据是否需要复杂的计算才能被详细说明。 在这种情况下,可以方便地实例化多个线程来详细说明不同的磁盘数据; 但只有在同一系统上有多个CPU时,这才很方便。

否则,多个线程会使HDD比必要的压力更大:来自不同线程的并发读取将发出读取操作以读取文件块(*),从而引入可能减慢系统速度的开销,具体取决于读取的文件数量和文件的大小。

按顺序读取文件。

(*)操作系统确实尝试按顺序存储相同的文件块,以加快读取操作。 磁盘碎片发生,因此非顺序碎片需要搜索操作,这需要更多时间来尊重同一位置的读取操作。 尝试并行读取多个文件,会导致一堆搜索,因为单个文件块是连续的,而多个文件块可能不连续。

切勿同时处理IO密集操作。 它的速度较慢,因为磁盘探测器在不同线程/文件之间切换时浪费了大量时间。

如果我在IO操作中有几个线程,我该怎么办? 并发生成操作,并以单线程执行它们。 我们有一个容器,比如ConcurrentQueue (或者你自己编写的线程安全队列),并且有10个线程,将从这些文件中读取1.txt 2.txt … 10.txt。 你将“读取请求”同时放入队列中,另一个线程处理所有请求(打开1.txt,得到你想要的,继续2.txt),磁盘探测器不会忙于切换线程/这种情况下的文件。

一个线程。 如果您正在同时阅读和写作并且您的目标是与您的源不同的磁盘,那么2个线程。 我将补充一点,如果您正在对文件执行其他操作(例如解压缩),则可以在第三个线程上完成解压缩部分。

举一些例子(我忽略了连接点,重新分析点……)

  • C:到C:1线程总计
  • C:到D:相同的物理磁盘,不同的分区:1个线程TOTAL
  • C:到D:不同的物理磁盘:2线程总计

我正在设想一个磁盘可以一次执行一个操作,并且每次“多任务”在不同的读/写之间切换时,它的速度会丢失。 机械磁盘有这个问题(但技术上NCQ可能有帮助)。 固态硬盘我不知道(但我知道如果你一次尝试做2个操作,USB棒非常慢)

我已经搜索了你是如何做到的……我还没有找到任何“具体”的例子,但我有一些指向Windows API的链接,你可以从这里开始:

我会说一个线程就足够了。 CPU可能能够运行多个线程,但硬盘的速度比CPU低许多个数量级。 即使运行更multithreading使得I / O请求更快(我不确定),也不会使硬盘实际读取速度更快。 它甚至可能会减慢速度。

如果它是单个硬盘驱动器,那么您希望最小化搜索时间。 因此,只能使用一个线程来读取和写入磁盘。

正如“C#”标记所暗示的那样,我假设您正在编写托管应用程序来执行磁盘I / O.

在这种情况下,我猜测用户级托管线程的数量是无关紧要的,因为它们不是实际执行磁盘I / O的线程。

据我所知,来自用户级托管线程的磁盘I / O请求将在内核级APC队列中排队,Windows I / O线程将处理它们。

因此,我想说在APC队列中排队的磁盘I / O请求的频率将与您的问题更相关。

我还没有看到任何允许将任何用户任务绑定到Windows I / O线程的.NET线程API。 但请注意,我的答案基于以下链接Windows I / O线程与托管I / O线程中的相对旧信息。

如果有人知道当前的Windows 7线程池模型与链接中的信息不同,请分享信息以教育我。

此外,您可能会发现以下链接有助于了解Windows文件I / O操作: 同步和异步I / O.

许多答案都是指HDD的数量。 请记住,它还取决于控制器的数量。 有时两个HDD由单个控制器管理。 另外:同一个硬盘上的两个分区不是两个硬盘!