1

加速しようとしているコードがいくつかあります。私の目標は、約 100 万個のファイルをダウンロードして保存することです。requests ライブラリを使用してコンテンツにアクセスしています。私はこれまで以上に混乱しています。ほとんどの Q/A は、適切な方法は、タスクが I/O バウンドである場合にスレッド化モジュールを使用することであり、サーバーに接続しているため、応答を待ってから応答をディスクに書き込むことであると示唆しています。バウンド。

しかし、私はこのようなものを読みました

1 つのプロセスに複数のスレッドが存在できます。同じプロセスに属するスレッドは、同じメモリ領域を共有します (まったく同じ変数を読み書きでき、互いに干渉する可能性があります)。

私のコードは次のようになります-スレッド化する前に

def create_list(some_ftp_site):
    # do some stuff to compare the list to
    #  the last list  and return the difference in the two

    return list_to_pull


def download_and save_the_file(some_url):
   thestring = requests.get(some_url).content
   file_ref = open(something)
   fileref.write(the_string)
   fileref.close()


if __name__ == '__main__'
   files_to_get = create_list(some_ftp_site)
   if len(files_to_get) != 0:
       for file_to_get in files_to_get:
           download_and_save(file_to_get)

どちらかを使用することは、私にとってディープエンドへのジャンプです。したがって、これをマルチスレッド化すると、たとえば、あるファイルの前半が別のファイルの後半に連結されるなど、予期しないことが起こる可能性があるのではないかと心配しています。

このタイプのタスクは、マルチプロセッシングまたはマルチスレッドに適していますか? 明らかに、2 つの異なるファイル部分が同じ変数に書き込まれるため、それらが連結されているかどうかはわかりません。

4

4 に答える 4

4

どちらでも機能しますが、マルチプロセッシングの方が安全で、おそらく実装が簡単です。特に Python の場合、Global Interpreter Lockは、マルチプロセッシングでは問題にならないのに対し、複数のスレッドが複数のコアからあまりメリットを得られないことを意味します。

于 2013-08-14T02:30:26.057 に答える
2

スレッド化は面倒になり、ミューテックスによる可変ロックが必要になる可能性があります。あなたのアプリケーションは、実装が簡単なマルチプロセッシングに適しているようです。あなたのコードを取り、それをメソッドに入れてください:

def download_and_save_the_file(some_url):
    thestring = requests.get(some_url).content
    #Make sure you create unique names
    something = unique_filename(some_url)
    file_ref = open(something)
    fileref.write(the_string)
    fileref.close()  

次に、マルチプロセッシングと URL のリストを使用してプールを作成します。並列ダウンロードは次のように進行します。

from multiprocessing import Pool,cpu_count

p = Pool(cpu_count()-1)
p.map(download_and_save_the_file,files_to_get)
于 2013-08-14T03:14:27.040 に答える
2

IO バウンド アプリを構築しているため、データのダウンロード中、ほとんどのアプリはブロックされた状態のままになります。これは、スレッド化またはマルチプロセッシングのどちらを使用しても当てはまります。本当に重要なデータをダウンロードしたい場合は、Python の gevent のような並行フレームワークを使用してください。他にもありますが、このフレームワークを使用すると、非ブロッキング状態で IO 呼び出しを実行できます。言い換えれば、まさにこの種の負荷を伴うこの種のアプリケーション向けに設計されています。

スレッド方式に進むと、最終的にスレッドをどれだけ作成できるかという壁にぶつかります。

並行して実行できるプロセスの数についても同じことが言えます。

たとえば、gevent を使用すると、非常に安価に作成できるため、何千もの「グリーン化された」スレッドを作成できます。

http://www.gevent.org

于 2013-08-14T02:38:55.437 に答える
1

アプリケーションを高速化したい場合は、マルチスレッドではなく、マルチプロセッシングを使用する必要があります。Python の GIL は、他の言語で使用されているように、スレッドが完全に独立した実行パスではないことを意味します。多くのプロセスを実行する場合は、Python をホストする OS を検討することをお勧めします。Windows でのプロセス間のコンテキスト切り替え時間は特に高速ではありません。

マルチプロセス/マルチスレッドアプリケーションと同様に、各プロセスまたはスレッドが適切な量の作業を行っていることを確認する必要があります。そうしないと、アプリケーションはすべてコンテキストスイッチングになり、実際の実行が少なくなります...

于 2013-08-14T05:20:35.183 に答える