2014-03-03 42 views
0

我有大約1.5 Gb的文件,我想將文件分成塊,以便我可以使用多處理來處理每個塊使用python中的pp(並行python)模塊。直到現在我已經在python中使用了f.seek,但是它需要很多時間,因爲它可能會逐字節地增加字節數。所以可以採用哪種替代方法? 我可以通過python的mrjob(map-reduce包)來做到這一點嗎?如何將文件分塊成多處理

示例代碼:我在做這樣的事情

def multi(i,slots,,file_name,date): 
f1=open(date+'/'+file_name,"rb") 
f1.seek(i*slots*69) 
data=f1.read(69) 
counter=0 
print 'process',i 
while counter<slots: 
    ##do some processing 
    counter+=1 
    data=f1.read(69) 

我的每一行都包含一個69個字節的元組數據和多功能的平行稱爲n倍(這裏n等於槽)來完成這項工作

+0

如果你有幾個1Gb文件,你可以讓每個線程處理一個這樣的文件。也許沒有必要將這些文件分成塊? –

+0

沒有,如果我必須處理只有一個文件,我必須把它分成塊 –

+0

好吧,那麼你有幾個文件的事實是不相關的在你的問題。我建議編輯你的文章,以便它開始於:「我有一個大約1 GB的文件...」等 –

回答

1

爲什麼不打開文件的多個句柄?這樣,你只需要爲每個句柄「尋找」一次。

f1 = open('file') 

f2 = open('file') 
f2.seek(100) # in practice the number would be <file size>/<no of threads> 

f3 = open('file') 
f3.seek(200) 
+0

我正在做同樣的方式,但正如我所說,它需要時間。事實上,由於這一點,通過多處理單個文件處理大約需要40秒,並沒有多處理它只需要25秒。 –

+4

多線程競爭讀取相同的文件通常會降低性能,除非您有專門的硬件和文件系統支持(包括多個I/O通道)。如果您的文件位於連接到具有單個I/O通道的計算機的硬盤上(這是許多臺式機的典型特性),您最好讓一個線程讀取該文件,然後將其分塊爲其他進程的塊處理。在每一次機會中儘可能多地記憶。 –

+0

這很有道理。 –

1

最簡單的方法是擁有一個讀取記錄並返回它的公共函數。但是該功能受鎖定保護。像下面的東西。請注意,我不是Python程序員,所以您必須解釋我的僞代碼。

f = open file 
l = new lock 

function read 
    acquire lock 
     read record 
    release lock 
    return record 

現在,啓動一個線程數,但不能超過你的處理器核心,其中的每一個做到這一點:

while not end of file 
    record = read(); 
    process record 

因此,而不是開始一個新的線程對每條記錄的,你有少數持續線程。

另一種方法是將線程專用於讀取。它讀取記錄並將它們放入線程安全隊列中。隊列被限制在一定的大小(100條記錄,10,000條記錄,無論如何)。處理線程從該隊列中讀取。這種方法的優點是讀線程可以在其他線程正在處理時填充隊列。處理線程可以很快獲得下一條記錄。

+0

沒有文件不是爲每個記錄打開,而是爲每個進程打開。所以如果我有5個進程,文件將被打開5次你的方法是好的,但在我的情況下,處理所需的時間比閱讀少得多。因此,無論如何,我必須平行閱讀。 –

+0

@AmanJagga:我的歉意。我讀錯了你的代碼。我已經更新了我的答案。 –

+1

@AmanJagga:你不能並行閱讀。磁盤一次只能做一件事。如果處理比讀取花費的時間少得多,那麼你的程序是I/O限制的,並且添加更多線程不會對你有所幫助。 *最好*你可以做的是有一個閱讀線程和一個處理線程,以便一些閱讀時間重疊處理時間。 –

相關問題