2016-04-11 2 views
0

私はPythonとマルチプロセッシングを使用して数千のイメージをダウンロードしようとしており、libsをリクエストしています。物事はうまく始まりますが、約100枚の画像があります。すべてがロックされ、私はそのプロセスを殺さなければなりません。私はPython 2.7.6を使用しています。ここでは、コードです:Pythonのリクエストとマルチプロセッシングで多数のイメージをダウンロードする

import requests 
import shutil 
from multiprocessing import Pool 
from urlparse import urlparse 

def get_domain_name(s): 
    domain_name = urlparse(s).netloc 
    new_s = re.sub('\:', '_', domain_name) #replace colons 
    return new_s 

def grab_image(url): 
    response = requests.get(url, stream=True, timeout=2) 
    if response.status_code == 200: 
     img_name = get_domain_name(url) 
     with open(IMG_DST + img_name + ".jpg", 'wb') as outf: 
      shutil.copyfileobj(response.raw, outf) 
     del response 

def main():           
    with open(list_of_image_urls, 'r') as f:     
     urls = f.read().splitlines()                
    urls.sort()          
    pool = Pool(processes=4, maxtasksperchild=2) 
    pool.map(grab_image, urls)      
    pool.close()         
    pool.join() 

if __name__ == "__main__": 
    main() 

編集:スレッドの代わりに、プロセスを使用するmultiprocessing.dummyするマルチプロセッシングのインポートを変更した後、私はまだ同じ問題が発生しています。それは私が時々動きのjpegストリームを1つの画像ではなく関連する問題を引き起こしていると思われます。この問題を処理するために、私はコンテキストマネージャを使用していて、私はFileTooBigExceptionを作成しました。私は、私が実際に画像ファイルや他のいくつかのハウスクリーニングをダウンロードし、私は以下のコードは、誰かのために役に立つかもしれないと思ったことを確認するチェック実装していないが:

class FileTooBigException(requests.exceptions.RequestException): 
    """File over LIMIT_SIZE""" 


def grab_image(url): 
    try: 
     img = '' 
     with closing(requests.get(url, stream=True, timeout=4)) as response: 
      if response.status_code == 200: 
       content_length = 0 
       img_name = get_domain_name(url) 
       img = IMG_DST + img_name + ".jpg" 
       with open(img, 'wb') as outf: 
        for chunk in response.iter_content(chunk_size=CHUNK_SIZE): 
         outf.write(chunk) 
         content_length = content_length + CHUNK_SIZE 
         if(content_length > LIMIT_SIZE): 
          raise FileTooBigException(response) 
    except requests.exceptions.Timeout: 
     pass 
    except requests.exceptions.ConnectionError: 
     pass 
    except socket.timeout: 
     pass 
    except FileTooBigException: 
     os.remove(img) 
     pass 

そして、いずれの提案の改善を歓迎します!

+1

ロックされているときにエラーや警告が表示されますか?ロックされている場所を特定できるかどうかを確認するためにデバッグを行ったことがありますか?常に同じ画像にロックされていますか? – Andy

+1

プロセスがハングアップしてもまだCPUを使用していますか?どのくらいのメモリが割り当てられていますか? 32ビットまたは64ビットを実行していますか?ロックアップするまでファイルを作成していますか? 0バイトのファイルなど、異常なゴミを残していますか?あなたがロックアップしたときにどれだけのディスク容量が残っていますか? –

答えて

1

multiprocessingをI/Oの並行処理に使用することに意味はありません。ネットワークI/Oでは、スレッドは何もしないでほとんどの時間だけ待っています。そしてPythonスレッドは何もしないのに優れています。したがって、プロセスプールの代わりにスレッドプールを使用してください。各プロセスは多くのリソースを消費し、I/Oバウンド・アクティビティには不要です。スレッドはプロセス状態を共有し、正確にあなたが探しているものです。

関連する問題