2013-06-10 31 views
5

Tôi có một kịch bản Python rất đơn giản bằng gevent.pool để tải xuống URL (xem bên dưới). Kịch bản chạy tốt trong một vài ngày và sau đó khóa lại. Tôi nhận thấy rằng việc sử dụng bộ nhớ là rất cao vào thời điểm đó. Tôi đang sử dụng gevent không chính xác?Script Python với Gevent Pool, tiêu thụ rất nhiều bộ nhớ, khóa

import sys 

from gevent import monkey 
monkey.patch_all() 
import urllib2 

from gevent.pool import Pool 

inputFile = open(sys.argv[1], 'r') 
urls = [] 
counter = 0 
for line in inputFile: 
    counter += 1 
    urls.append(line.strip()) 
inputFile.close() 

outputDirectory = sys.argv[2] 

def fetch(url): 
    try: 
     body = urllib2.urlopen("http://" + url, None, 5).read() 
     if len(body) > 0: 
      outputFile = open(outputDirectory + "/" + url, 'w') 
      outputFile.write(body) 
      outputFile.close() 
      print "Success", url 
    except: 
     pass 

pool = Pool(int(sys.argv[3])) 
pool.map(fetch, urls) 
+0

Âm thanh như rò rỉ bộ nhớ trong 'gevent'. Một google nhanh chóng cho 'python gevent memory leak' trả về số lượng truy cập đáng ngạc nhiên lớn, mặc dù bạn có thể ở vị trí tốt hơn để xác định xem có bất kỳ trường hợp nào áp dụng cho trường hợp cụ thể của bạn hay không. – Aya

Trả lời

2
 body = urllib2.urlopen("http://" + url, None, 5).read() 

Trên dòng đọc toàn bộ nội dung trong bộ nhớ như là một chuỗi. Để ngăn chặn điều đó, hãy thay đổi hàm fetch() như sau:

def fetch(url): 
    try: 
     u = urllib2.urlopen("http://" + url, None, 5) 
     try: 
      with open(outputDirectory + "/" + url, 'w') as outputFile: 
       while True: 
        chunk = u.read(65536) 
        if not chunk: 
         break 
        outputFile.write(chunk) 
     finally: 
      u.close() 
     print "Success", url 
    except: 
     print "Fail", url 
+0

với mở (...) dưới dạng outputFile ... thay vì thử – zinking