12

それぞれが threading.local オブジェクトにアクセスしようとする 2 つのプロセス (サンプル コードを参照) があります。以下のコードは、「a」と「b」を (どちらの順序でも) 出力することを期待しています。代わりに、「a」と「a」を取得します。まったく新しいプロセスを起動するときに、threading.local オブジェクトをエレガントかつ堅牢にリセットするにはどうすればよいですか?

import threading
import multiprocessing
l = threading.local()
l.x = 'a'
def f():
    print getattr(l, 'x', 'b')
multiprocessing.Process(target=f).start()
f()

編集: 参考までに、multiprocessing.Process の代わりに threading.Thread を使用すると、期待どおりに動作します。

4

3 に答える 3

9

あなたが言及した両方のオペレーティング システムは Unix/Linux ベースであるため、同じfork()ing API を実装しています。fork()は、プロセス オブジェクトを、そのメモリ、ロードされたコード、開いているファイル記述子、およびスレッドと共に完全に複製します。さらに、新しいプロセスは通常、最初のメモリ書き込み操作まで、カーネル内でまったく同じプロセス オブジェクトを共有します。これは基本的に、スレッド ローカル変数とともに、ローカル データ構造も新しいプロセスにコピーされることを意味します。したがって、同じデータ構造があり、l.xまだ定義されています。

新しいプロセスのデータ構造をリセットするには、プロセス開始関数で最初にクリア メソッドを呼び出すことをお勧めします。たとえば、親プロセス pid を保存しprocess_id = os.getpid()て使用することができます

if process_id != os.getpid(): 
   clear_local_data()

子プロセスのメイン関数。

于 2011-09-02T15:44:16.983 に答える
3

そのドキュメントthreading.localで明確に説明されているように、プロセスではなくスレッドのトリックを行うためです。

インスタンスの値は、スレッドごとに異なります。

プロセスについては何もありません。

そして multiprocessing docからの引用:

ノート

multiprocessing には、threading.active_count()、threading.enumerate()、threading.settrace()、threading.setprofile()、threading.Timer、またはthreading.localの類似物は含まれていません。

于 2011-09-02T15:33:22.390 に答える