2013-06-10 6 views
5

Mam bardzo prosty skrypt w języku Python, korzystający z gevent.pool do pobierania adresów URL (patrz poniżej). Skrypt działa dobrze przez kilka dni, a następnie blokuje. Zauważyłem, że wykorzystanie pamięci jest w tym czasie bardzo wysokie. Czy używam niepotrzebnie geitu?Skrypt Pythona z pulą Gevent, zużywa dużo pamięci, blokuje się

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

Brzmi jak wyciek pamięci w 'gevent'. Szybki google dla 'python gevent memory leak' zwraca zaskakująco dużą liczbę trafień, chociaż prawdopodobnie jesteś w lepszej pozycji, aby ustalić, czy któryś z nich dotyczy Twojego konkretnego przypadku. – Aya

Odpowiedz

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

Powyżej linii odczytuje całą zawartość pamięci jako ciąg znaków. Aby temu zapobiec, zmień metodę fetch() w następujący sposób:

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

z otwartym (...) jako outputFile ... zamiast spróbuj – zinking

Powiązane problemy