2016-07-08 180 views
1

我试图读取30GB(2500万行)的大文件的文件。我想编写一个代码,它将创建一个线程池,每个线程将并行读取1000行(第一个线程将读取前1000行,第二个线程读取下一个1000行,等等)。 我已经阅读了整个文件并创建了线程池,但现在我坚持如何确保每个线程只读取1000行,并跟踪已读取的行号以便下一个线程不必读取那些线。使用多线程读取30GB文件

+1

一旦你解决了这个问题,你使用磁力驱动器?无论如何,这将会是IO界限。 –

+0

让1个线程读取大块(30GB)通常会比25000个线程读取小块快。 25000个线程有很多开销,如果它是1个文件驻留在1个磁盘上,那么每个线程都必须等待队列中的访问时间。 –

+5

您通常应该只有一个线程处理外部资源,例如文件。不要试图分发不会提高性能的I/O,而是让读者将每个捆绑包发布到并发队列中和/或发送给执行程序任务。 – chrylis

回答

0

A.如果是acceaptable所有的线程都行大致均等的,您可以:

  1. 假设线程池的大小是N,1号线力求文件偏移0和阅读[0,30GB/N ),第二个线程寻求抵消30GB/N,读取[30GB/N,30GB/N * 2)等。
  2. 第二个线程可能不在一行的开头,而是在一行的中间。没关系。只需跳过paritial行,并阅读完整的行。第一条线可以以部分线结束。没关系,只要继续阅读,直到阅读'\ n'。其余的线程做同样的事情。

B.如果所有线程都必须有行正好euqal数,这是说1000线,您可以:

  1. 有一个线程读取整个文件,建立索引地图。该地图具有像line0〜line999开始偏移量0,线1000〜line1999开始偏移量13521等信息...
  2. 所有线程从相应的偏移读取文件,并读取1000行。

方法A读取文件1次。方法B读取文件2次。

使用方法A或B,可以使所有线程并行处理文件(转换,提取,清理..)。但是,如果处理速度非常快,则界限就是磁盘速度。然后你的应用程序被IO绑定。你应该只需要一个线程读取文件并连续执行处理。

+0

方法B是我追求的逻辑,但后来遇到了线程之间已经读取的行号问题。读取文件的单个线程将文件内容放入队列中,然后在读取特定行的队列的同时维护一个线程安全计数器以指示已读取的行,这很麻烦 –

+0

您说“第一个线程会先读取1000行“我认为这组行必须一起处理。如果没有这样的约束,只要先读取第一个小N(1,2,是ok)行并给第一个线程,然后再写第二个小N行给第二个线程。等等。 – waltersu

+0

@ChristineDsouza你已经有了这个方法。只需向我们展示您的代码和有关线程安全问题的问题。 – waltersu