2016-07-08 173 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