2012-05-21 87 views
1

當queue.put()的速度比queue.get()速度快時,我發現P1進程將使用大內存(因爲P1從一個大型文本文件中不斷插入行) 。即使P2已經完成從隊列中排隊。 P1使用的內存不會釋放。如何解決這個問題?以下是樣本和測試代碼。多處理隊列不釋放內存

謝謝!

import time 
from multiprocessing import Process, Queue 

def addline(q): 
    f = file('a big text file','r') 
    line = True 
    while line: 
     line = f.readline() 
     q.put(line, False) 
    f.close() 
    print "P1:finished" 
    while 1: 
     time.sleep(2) 

def getline(q): 
    f = file('/tmp/bak','w') 
    line = True 
    while line: 
     line=q.get() 
     f.write(line) 
     time.sleep(0.01) 
    f.close() 
    print "p2:finished" 



if __name__ == "__main__": 
    q = Queue() 
    p1 = Process(name="addline", target=addline, args=(q,)) 
    p2 = Process(name="getline", target=getline, args=(q,)) 
    p1.start() 
    p2.start() 

編輯: 我嘗試讀取文本文件(44MB),然後觀察的/ proc/PID/smaps。我發現沒有發佈的內存在堆中變成Private_Dirty。

00fb3000-04643000 rw-p 00000000 00:00 0         [heap] 
Size:    55872 kB 
Rss:    55844 kB 
Pss:    55163 kB 
Shared_Clean:   0 kB 
Shared_Dirty:  1024 kB 
Private_Clean:   0 kB 
Private_Dirty:  54820 kB 
Referenced:  54972 kB 
Swap:     0 kB 
KernelPageSize:  4 kB 
MMUPageSize:   4 kB 

+0

你在'getline()'中用'while 1:q.get()'做什麼? –

+0

在這個測試案例中,我只想保留P2。我已將其刪除。謝謝。 – jess

+1

您是否考慮過爲您的隊列設置限制?如果閱讀過程無法跟上,那麼沒有限制,整個東西必須緩衝在隊列中。 – mata

回答

1

,因爲它不再被引用的Python的垃圾收集儘快刪除對象。只要寫入速率能夠跟上存儲硬件的讀取速率,就必須從兩個獨立的線程/進程同時寫入文件時讀取文件的內容,而不必增加內存和佔用很少的內存。我相信當你使用更適合你的用例的Python語言結構時,你的問題就會消失。我會盡力對此發表評論。

用於讀取文件一行行,你應該使用以下概念:

with open('filepath') as f: 
    for line in f: 
     do_something_with(line) 

您不必明確.close()文件即可。這同樣適用於寫入文件。閱讀關於這裏的with聲明:http://effbot.org/zone/python-with-statement.htm

從我的角度來看,對於使用情況下,你已經提出,一個multiprocessing.Pipe代替multiprocessing.Queue會因爲「流式」應用程序的更合適。將原始文件內容表示爲隊列中的項目似乎很奇怪。此外,如果您使用線程而不是獨立的子進程(那麼您應該使用os.pipe進行線程間通信)**,您可以擺脫很多通信開銷。無論如何,你應該在啓動它們之後線程和子進程。

**對於您的用例(複製文件),全局解釋器鎖(GIL)不會是性能問題。

+0

感謝您的回覆!在我的真實情況下,我必須收集很多來源。爲了避免GIL問題,我使用了multiprocessing和multiprocessing.Queue。關於閱讀文件,我使用過發生器。在Queue.get之後,P2會分析它,所以P2比P1慢。然後P1將使用內存並且不會釋放它。我不知道如何解決它。 – jess

+0

如果您的數據分析速度遠遠低於讀取文件的速度,並且您不希望擁有較大的緩衝區(即增加內存使用量),則除了實現反饋機制外,沒有其他選擇了:讀取器需要一些指示以何時暫停讀取數據。 –

+0

在正常情況下,分析儀速度不夠快,因此讀卡器不使用存儲器。但恐怕有一些例外。我很好奇緩衝區爲什麼不釋放,即使讀取器已經從緩衝區獲取數據。謝謝! – jess