8

Python マルチプロセッシングを学習しようとしています。

http://docs.python.org/2/library/multiprocessing.html「関連する個々のプロセス ID を表示するには、ここに拡張された例を示します:」の例から

from multiprocessing import Process
import os

def info(title):
    print title
    print 'module name:', __name__
    if hasattr(os, 'getppid'):  # only available on Unix
        print 'parent process:', os.getppid()
    print 'process id:', os.getpid()

def f(name):
    info('function f')
    print 'hello', name

if __name__ == '__main__':
    info('main line')
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()

私は正確に何を見ているのですか?def f(name): は info('main line') が終了した後に呼び出されることがわかりますが、この同期呼び出しはとにかくデフォルトになります。同じプロセス info('main line') が def f(name): の親 PID であることがわかりますが、それについて「マルチプロセッシング」とは何かわかりません。

また、join() では「join() メソッドが呼び出されたプロセスが終了するまで、呼び出し元のスレッドをブロックします」。呼び出しスレッドがどうなるかはわかりません。この例では、join() は何をブロックしているのでしょうか?

4

1 に答える 1

25

簡単に言えば、どのようmultiprocessingに機能するか:

  • Process()元のプログラムのコピーを生成します (forkまたは Unix ライクなシステムでは同様のものです) (実際の がない Windows では、forkこれは注意が必要であり、モジュールのドキュメントに記載されている特別な注意が必要です)。
  • コピーはオリジナルと通信して、(a) それがコピーであり、(b) 終了してtarget=関数を呼び出す必要があることを判断します (以下を参照)。
  • この時点で、オリジナルとコピーは異なる独立したものになり、同時に実行できます。

これらは独立したプロセスであるため、独立したグローバル インタープリター ロック (CPython 内) を備えているため、他の下位レベル (OS ) 資力。それが「マルチプロセッシング」の部分です。

もちろん、ある時点で、独立していると思われるこれらのプロセス間でデータをやり取りする必要があります。たとえば、1 つ (または多数) のワーカー プロセスからの結果を「メイン」プロセスに送り返す場合などです。(誰もが完全に独立しているという例外は時折ありますが、それはまれです...さらに、 によって開始される起動シーケンス全体が存在しp.start()ます。)したがって、作成された各Processインスタンス (上記の例では <code>p) には通信があります。親の作成者へのチャネル、およびその逆のチャネル (対称接続です)。multiprocessingモジュールはモジュールを使用しpickleてデータを文字列 (ファイルに格納できるのと同じ文字列) にpickle.dump変換し、そのデータをチャネルを介して "下向き" に送信し、ワーカーに引数などを送信し、"上向き" に送信します。

最終的に、結果の取得がすべて完了すると、ワーカーは (target=関数から戻ることによって) 終了し、親に完了を通知します。すべてが閉じられてクリーンアップされるようにするために、親はp.join()ワーカーの「I'm done」メッセージを待つように呼び出す必要があります (実際には、exitUnix っぽいシステムの OS レベルです)。

2 つの出力メッセージは基本的にまったく時間がかからないため、この例は少しばかげています。したがって、それらを「同時に」実行しても測定可能な利点はありません。しかし、 を出力するだけでなくhellof最初の 100,000 桁の π (3.14159...) を計算するとします。次に、e の最初の 100,000 桁 (2.71828...) を計算する別のターゲットを使用して、別Processのを生成できます。これらは独立して実行されます。次に、親は を呼び出して、両方が完了するのを待つことができます (または、さらに多くのワーカーを生成して、より多くの作業を行い、より多くの CPU を占有するか、オフにしてしばらくの間独自の作業を行うことさえできます)。p2gp.join()p2.join()

于 2013-08-11T08:09:04.107 に答える