2017-02-02 17 views
2

Pythonのマルチプロセッシング

私のpythonスクリプトは、割り当てられたディレクトリの各ログを調べ、特定の列の合計を計算し、ファイルに書き込み、次のログファイルに移動します。私がこれをしたときに、私はシステム内のすべてのコアを使用していないことに気付きました。だから私は、「インポートマルチプロセッシングを有効にした場合、この

script1.py < folder 1 (contains logs 1-5 , write to report1-5.txt) 
script2.py < folder 2 (contains logs 6-10, write to report6-10.txt) 
script3.py < folder 3 (contains logs 11-15, write to report11-15.txt) 
script4.py < folder 4 (contains logs 16-20, write to report16-20.txt 

は、理想的には私がちょうどscript1.py <フォルダ1(全20件のログが含まれており、REPORT.TXTに書き込みます)

を持つことになり、私がやったコアの多くを使用します"私は1つのスクリプトと多くの労働者が異なるファイルを通過することを達成することができますか、それは販売log.gzファイルで作業しようとしている多くの労働者ですか?または私が情報を逃しているのですか?

答えて

2

私があなたの質問を正しく理解していれば、gzipで圧縮されたログファイルの処理を高速化する良い方法を探しています。

答えが必要なのは、現在のプロセスがCPUバウンドまたはIOバウンドの場合です。つまり、現在script.py < folder 1を実行していて、それを見ているときなどです。 topを使用すると、プロセスのCPU使用率は最大100%になりますか?はいの場合、プロセスはCPUバウンドです(つまりCPUがボトルネックです)。これが当てはまる場合は、Pythonでの並列化が役に立ちます。そうでない場合(gzファイルが別のディスクにない限り、ディスクがボトルネックになることはないと思います)、これ以上スピードを上げることはないので気にする必要はありません。

  1. のpython:あなたが示唆したように、マルチプロセッシングを使用する必要がありますが、基本的に2つのオプションがあり並列化する

    。それを可能にするために、あなただけのマルチプロセッシングをインポートすることはできません。しかし、あなたは例えば、明示的に各プロセスを行うために必要なものを言う必要があるでしょう:

    from multiprocessing import Pool, Queue 
    
    def crunch_file(queue): 
        while not queue.empty() 
         filename = queue.get() 
         # gunzip file, do processing, write to reportx-y.txt 
    
    if __name__ == '__main__': 
        queue = Queue() 
        # put all filenames into queue with os.walk() and queue.put(filename) 
        pool = Pool(None, crunch_file, (queue,)) 
        pool.close() # signal that we won't submit any more tasks to pool 
        pool.join() # wait until all processes are done 
    

    注意すべきいくつかのこと:

    • Pool(None, ...)のpythonを使用しては把握しますコアの数からあなたが持っているとQueueあなたはアイドリングプロセスを持っていることはありませんすることができます使用して1つのCPUコアごとにプロセス
    • 開始します:プロセスの一つは、自分のファイルで行われている場合、それはキューの次になりますが
  2. bash:あなたはパイソンズのマルチプロセッシングに精通していないようで、さまざまなプロセスはお互いに話す必要はありません。 4つのPythonプログラムが並行しています。

    script.py < folder 1 & 
    script.py < folder 2 & 
    script.py < folder 3 & 
    script.py < folder 4 & 
    
+0

これは素晴らしい説明でした。だから1と2は基本的に同じことを広げています。 – chowpay

+0

@chowpay基本的に彼らは同じことをしています、はい。 Pythonを使用すると、より均等に負荷をコアに分散できるので、より多くの制御が可能になります。さらに、フォルダ数がコア数よりも少なくても、すべてのコアを利用できます。つまり、bashソリューションは実装がはるかに簡単で、ユースケースには十分かもしれません。 – hansaplast

0

は、いや、あなたは正しい軌道に乗っています。私はいつも似たようなことをしています。はるかに速く実行されます。最初にファイルを解凍する必要があります。 Globのファイルをピックアップして、ファイル名のリストでpool.map(fn、lst)に渡します。SSDを追加する必要があります。通常のHDを使用している場合はスピードの向上はありませんすべて悲しいことに。SSDはこれには最適です。キューを使用しないで閉じる、結合する、すべて不要なので、map()を使用してください

+0

6〜7ギガバイトのlog.gzファイルの100sをすばやく解凍する方法はありません。私はそれらをgz形式でメモリに読み込んで処理し、gz形式で出力します – chowpay

関連する問題