【问题标题】:Multithreaded file access多线程文件访问
【发布时间】:2009-06-11 18:54:42
【问题描述】:

我正在编写一个十六进制编辑器程序,我正在考虑用户何时尝试打开一个非常大的文件 (3GB+)。当整个文件已经加载了一些数据时,我不希望用户整天坐在那里加载整个文件。

所以这是我的问题,是否可以让多个线程同时在不同的位置读取文件(而不是写入),然后一旦读取了某个阈值的数据 1,该线程就会显示其数据而其他人继续阅读?这会给我带来性能提升吗?或者内存带宽会降低我使用多线程获得的任何速度增益吗?

【问题讨论】:

    标签: multithreading file


    【解决方案1】:

    对于十六进制编辑器,无需将整个文件读入内存。用户只能查看或修改数据,不能插入或删除。

    您可以简单地使用内存映射文件。访问时会自动读取数据,并且只会读取显示的块。这提供了快速滚动和跳转到文件中的任何位置。

    【讨论】:

      【解决方案2】:

      我不确定您期望什么性能提升。 . .有一个数据流从磁盘流出,从磁盘读取多个线程只会增加争用,并且可能会因为磁盘磁头因竞争请求而来回弹跳而导致速度变慢。

      您应该考虑改为使用异步 IO,并在数据进入时立即处理数据,以使您的应用程序显示为响应式。

      【讨论】:

      • 我以为带宽会妨碍它,但我还是想问一下。
      • +1 用于异步 IO。我不敢相信我没有想到这一点。这绝对是最理智的方式...
      • 异步 I/O 到底是什么意思?
      • @samoz:这意味着你告诉操作系统开始做 IO,你可以做其他事情,然后在数据加载后随时实际使用数据。
      【解决方案3】:

      您可能不想使用多个线程。即使在多核 CPU 上,仍然只有一条通往磁盘的路径,因此您可能不会获得性能提升(磁盘访问比内存慢得多)。

      虽然一次加载和显示一点点,但您有一个好主意。只需在一个线程中执行此操作。大致读取第一个兆字节,显示它,然后在后台执行下一个,等等。

      你是对的,你可能想要一个用于 GUI 的单独线程。这就是为什么BeOS 与当时的其他操作系统相比反应如此令人难以置信的原因之一。它为不同的任务使用了许多不同的线程。

      只是不要指望从磁盘读取的多个线程会有所帮助。

      另外,您可以使用aio_read() 在 Linux 上进行异步 IO。如果您使用的是 Windows,请尝试使用谷歌搜索“windows 异步 io”(我不太确定您是如何做到的;我不使用 Windows)。

      【讨论】:

      • 那么也许 I/O 是一个独立于 GUI 的线程?然后,如果 GUI 试图查看尚未检索的数据,我可以中断 I/O 线程并获取请求的数据。
      • @Samoz - 这正是正确的方法 - 不要阻塞 IO 上的 UI 线程。
      【解决方案4】:

      忘记阅读整个文件。只需在用户需要时读取小块。在十六进制编辑器上更容易,因为内容不会影响布局。

      读取一屏数据在几毫秒内完成,用户在四处走动时不会意识到它已经完成,而不是提前读取整个数据

      【讨论】:

        【解决方案5】:

        正如@bill 所说,您需要使用内存映射文件。我认为您会发现以下教程非常有价值:

        以上教程应该为您提供所需的所有信息。

        【讨论】:

          【解决方案6】:

          我认为您最好使用异步又名非阻塞 I/O。这意味着您可以发送读取请求,然后继续处理,然后继续获取请求的结果。因此,单个线程可以重叠处理和 I/O。用谷歌搜索一下就能找到适合您平台的 API 文档。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多