0

重複の可能性:
マルチプロセッシングによる Python VM のインスタンスの起動が多すぎる

私はPythonマルチプロセスを使用してWebフェッチを並列化しようとしていますが、マルチプロセッシングを呼び出すアプリケーションが、呼び出したい関数だけでなく、複数回インスタンス化されることがわかりました(呼び出し元がいくつかの依存関係を持っているため、これは私にとって問題です)インスタンス化が遅いライブラリ - 並列処理によるパフォーマンスの向上のほとんどが失われます)。

私は何を間違っていますか、またはこれをどのように回避しますか?

my_app.py:

from url_fetcher import url_fetch, parallel_fetch
import my_slow_stuff

my_slow_stuff.py:

if __name__ == '__main__':
    import datetime
    urls = ['http://www.microsoft.com'] * 20
    results = parallel_fetch(urls, fn=url_fetch)
    print([x[:20] for x in results])

class MySlowStuff(object):
    import time
    print('doing slow stuff')
    time.sleep(0)
    print('done slow stuff')

url_fetcher.py:

import multiprocessing
import urllib

def url_fetch(url):
    #return urllib.urlopen(url).read()
    return url

def parallel_fetch(urls, fn):
    PROCESSES = 10
    CHUNK_SIZE = 1
    pool = multiprocessing.Pool(PROCESSES)
    results = pool.imap(fn, urls, CHUNK_SIZE)
    return results

if __name__ == '__main__':
    import datetime
    urls = ['http://www.microsoft.com'] * 20
    results = parallel_fetch(urls, fn=url_fetch)
    print([x[:20] for x in results])

部分的な出力:

$ python my_app.py
doing slow stuff
done slow stuff
doing slow stuff
done slow stuff
doing slow stuff
done slow stuff
doing slow stuff
done slow stuff
doing slow stuff
done slow stuff

...

4

2 に答える 2

1

os.fork()Pythonはこのプラットフォームに実装されていないため、Windows用のPythonマルチプロセッシングモジュールの動作は少し異なります。特に:

メインモジュールの安全なインポート

メインモジュールが、意図しない副作用(新しいプロセスの開始など)を引き起こすことなく、新しいPythonインタープリターによって安全にインポートできることを確認してください。

ここで、グローバルclass MySlowStuffは常にWindowsで新しく開始された子プロセスによって評価されます。これを修正するには、。class MySlowStuffの場合にのみ定義する必要があります__name__ == '__main__'

16.6.3.2を参照してください。詳細については、 Windowsを参照してください。

于 2011-10-31T13:31:45.023 に答える
0

Windowsのマルチプロセッシングモジュールは、Unix/Linuxの場合と同じようには機能しません。Linuxでは、forkコマンドを使用し、フォークされたときと同じように、すべてのコンテキストが新しいプロセスにコピー/複製されます。

システムコールforkはWindowsに存在せず、マルチプロセッシングモジュールは新しいPythonプロセスを作成し、すべてのモジュールを再度ロードする必要があります。これが、PythonlibドキュメントでWindowsでマルチプロセッシングif __name__ == '__main__'使用するときにトリックを使用するように強制する理由です。

この場合の解決策は、代わりにスレッドを使用することです。このケースはIOバウンドプロセスであり、GILの問題を回避するマルチプロセッシングの利点は影響しません。

詳細については、http://docs.python.org/library/multiprocessing.html#windowsをご覧ください。

于 2011-10-31T13:32:21.077 に答える