9

こんにちは、私は現在Pythonでマルチプロセッシングを使用しています。そして、あるタスクの処理が完了したときに各プロセスがインクリメントできる単純なカウンター変数が存在するかどうか疑問に思っています(合計でどれだけの作業が行われたかのようなものです)。

Value の API を調べましたが、可変だとは思わないでください。

4

1 に答える 1

25

Value確かに変更可能です。モジュールから必要なデータ型を指定するctypesと、それを変更できます。これを示す完全な動作スクリプトを次に示します。

from time import sleep
from ctypes import c_int
from multiprocessing import Value, Lock, Process

counter = Value(c_int)  # defaults to 0
counter_lock = Lock()
def increment():
    with counter_lock:
        counter.value += 1

def do_something():
    print("I'm a separate process!")
    increment()

Process(target=do_something).start()
sleep(1)
print counter.value   # prints 1, because Value is shared and mutable

ValueEDIT:Luperは、値がデフォルトでロックされていることを下のコメントで正しく指摘しています。これは、割り当てが複数の操作で構成されている場合でも (多くの文字である可能性がある文字列の割り当てなど)、この割り当てはアトミックであるという意味で正しいです。ただし、カウンターをインクリメントするときは、私の例で提供されているように、外部ロックが必要です。インクリメントは現在の値をロードしてからインクリメントし、結果をValue.

したがって、外部ロックがないと、次の状況に陥る可能性があります。

  • プロセス 1 は、カウンターの現在の値を (アトミックに) 読み取り、インクリメントします。
  • プロセス 1 がインクリメントされたカウンタを に戻す前にValue、コンテキスト スイッチが発生します。
  • プロセス 2 は、カウンターの現在の (インクリメントされていない) 値を (アトミックに) 読み取り、それをインクリメントし、インクリメントされた結果を (アトミックに) に代入します。Value
  • プロセス 1 は、インクリメントされた値を (アトミックに) 割り当て、プロセス 2 によって実行されたインクリメントを吹き飛ばします。
于 2009-08-05T13:46:06.623 に答える