3
import multiprocessing as mp

def delay_one_second(event):
    print 'in SECONDARY process, preparing to wait for 1 second'
    event.wait(1)
    print 'in the SECONDARY process, preparing to raise the event'
    event.set()

if __name__=='__main__':
    evt = mp.Event()
    print 'preparing to wait 10 seconds in the PRIMARY process'
    mp.Process(target = delay_one_second, args=(evt,)).start()
    evt.wait(10)
    print 'PRIMARY process, waking up'

このコード (cmd.exe 内の "python module.py" コマンドを使用してモジュール内から適切に実行) は、驚くべき結果をもたらします。

メイン プロセスは明らかに 1 秒だけ待ってからウェイクアップします。これが発生するのは、セカンダリ プロセスがメイン プロセス内のオブジェクトへの参照を持っていることを意味します。

どうすればいいの?プロセス間でオブジェクトを共有するには、multiprocessing.Manager() を使用する必要があると予想していましたが、これはどのように可能ですか?

つまり、プロセスはスレッドではなく、同じメモリ空間を使用すべきではありません。ここで何が起こっているのか、誰にもアイデアがありますか?

4

2 に答える 2

2

簡単に言えば、共有メモリは別のプロセスによって管理されていないということです。オペレーティング システム自体によって管理されます。

ソースをブラウジングすると、これがどのように機能するかを確認できますmultiprocessing。オブジェクトがとEventを使用していることがわかります。どちらも、オブジェクトが提供するロック動作に依存しています。これは、c で実装され、 (POSIX) または(Windows)に依存するオブジェクトをラップします。SemaphoreConditionSemLock_multiprocessing.SemLocksem_openCreateSemaphore

これらは、オペレーティング システム自体によって管理される共有リソース (この場合は名前付きセマフォ) へのアクセスを可能にする c 関数です。それらはスレッド間またはプロセス間で共有できます。OSがすべてを処理します。新しいセマフォが作成されると、ハンドルが与えられます。次に、そのセマフォへのアクセスが必要な新しいプロセスが作成されると、ハンドルのコピーが与えられます。次に、そのハンドルをsem_openまたはCreateSemapohreに渡し、オペレーティング システムは新しいプロセスに元のセマフォへのアクセスを許可します。

したがって、メモリ共有されていますが、同期プリミティブに対するオペレーティング システムの組み込みサポートの一部として共有されています。つまり、この場合、共有メモリを管理するために新しいプロセスを開く必要はありません。オペレーティング システムがそのタスクを引き継ぎます。しかし、これが可能Eventなのは、動作するのにセマフォよりも複雑なものを必要としないからです。

于 2013-04-21T21:18:28.643 に答える
2

ドキュメントによると、マルチプロセッシングモジュールはスレッド API に従っています。私の推測では、「フォーク」に似たメカニズムを使用していると思います。スレッドをフォークすると、OS は現在のプロセスのコピーを作成します。これは、すべての変数とグローバルを含むヒープとスタックをコピーすることを意味し、それがあなたが見ているものです。

以下の関数を新しいプロセスに渡すと、自分で確認できます。

def print_globals():
    print globals()
于 2013-04-21T18:31:13.640 に答える