4

私はマルチプロセッシングが初めてで、Python 3.2 で 1 つのスレッドでカウンターが無期限に増加する単純なプログラムを作成しようとしています。値に達したら、マルチプロセッシング スレッドを閉じて、プログラムが "Process Complete" ステートメントを表示するようにします。

私が理解している限り、プログラムは次のようになります (指定された値は 10 です)。

import multiprocessing as mp


def Counter():
    i=1
    while i > 0:
        print("i: ",i)
        i+=1


def ValueTester(i):
    if i >= 10:
        *End Counter Function Thread*


if __name__ == '__main__':

    *Begin multiprocessing, one thread for "Counter" and a second for "ValueTester"*

    print("Process Complete")

疑似コードが曖昧で申し訳ありません。いくつかの異なる例と一緒に Python のドキュメントを読みましたが、簡単な解決策が見つからないようです。

さらに、これが機能したら、指定された停止値を設定するにはどうすればよいでしょうか (つまり、変数をValueTester単に使用するのではなく、に渡します10)。

ご助力ありがとうございます。

4

2 に答える 2

5

ここでは、スレッドとプロセスを明確に区別するように注意する必要があります。

スレッドはすべて同じプロセスで動作します。アクセスされる値は、スレッド間で共有できます。値がスレッドによって保護されている場合にのみ、安全な (調整された) 方法でスレッドによって値を変更できます。threading.Lock変更前です。Python と PyPy の最も一般的な実装である CPython では、Jython や Iron Python などの他の実装とは対照的に、GIL (グローバル インタープリター ロック) によって複数のスレッドが同時に実行されるのを防ぎます。そのため、CPython では、複数のスレッドが実際には同時にではなくシリアルに実行されます。それでも、ネットワーク (I/O) アクティビティの待機に多くの時間が費やされるため、多くの Web サイトのクエリなど、I/O を多用する作業には複数のスレッドが役立ちます。したがって、数学的計算のように CPU を集中的に使用するタスクと比較して、複数のスレッドが 1 つの CPU へのアクセスを争って待機する必要はありません。

以上のことをすべて言ったので、スレッドではなく、複数のプロセスを扱っています。プロセスは互いに独立しています。利用可能であれば、複数の CPU で同時に実行できます (CPython を含む)。プロセスを生成すると、グローバル値が元のプロセスから生成されたプロセスにコピーされます。Linux などの一部の OS では、「copy-on-write」を備えているため、プロセスが値を上書きしようとするまで、値は実際にはプロセス間で共有されます。その時点で値はコピーされ、他のプロセスから独立します。したがって、値を変更すると、2 つのプロセスは同じ名前の 2 つの変数になりますが、まったく異なる値を持つことができます

プロセス間で状態を共有しやすくするために、マルチプロセッシング モジュールによって提供される特別なオブジェクトがあり ます。これらには、、、が含まmp.Valuemp.Arrayます mp.Manager。これらのオブジェクトを使用するとき は、別のプロセスが同じことをしようとしている間に、あるプロセスが値を変更するのを防ぐためにa も使用する必要があることに注意してください。mp.Lockただし、ロックが解除されるまで待機する必要があるため、ロックもプロセスを遅くします。

別のプロセスで条件に達したときにプロセスにシグナルを送るには、次を使用しますmp.Event

import multiprocessing as mp
import time

def Counter(i, event, lock):
    with lock:
        i.value = 1
    while i.value > 0 and not event.is_set():
        print("i: ", i.value)
        with lock:
            i.value += 1


def ValueTester(i, stopval, event):
    while True:
        if i.value >= stopval:
            event.set()
            break
        else:
            time.sleep(0.1)


if __name__ == '__main__':
    num = mp.Value('d', 0.0)
    # A lock is not absolutely necessary here since only one process modifies
    # num, but I'm including it since it is necessary (to avoid race conditions)
    # in the more usual case when multiple processes may modify num.
    lock = mp.Lock()
    event = mp.Event()
    counter = mp.Process(target=Counter, args=(num, event, lock))
    counter.start()
    tester = mp.Process(target=ValueTester, args=(num, 10, event))
    tester.start()
    tester.join()
    counter.join()
    print("Process Complete")

マルチプロセッシングの使用例については、Doug Hellman の Python Module of the Week チュートリアル を参照してください。

于 2013-09-30T14:24:26.297 に答える