web-dev-qa-db-ja.com

Pythonマルチプロセッシングクラスメソッド

そのメソッドを使用してクラスフィールドを変更しようとしていますが、メソッドを挿入すると機能しません。

マルチプロセッシングインポートプロセスから

class Multi:
    def __init__(self):
        self.x = 20


    def loop(self,):
        for i in range(1,100):
            self.x = i

M = Multi()

p = Process(target=M.loop)
p.start()

このプログラムを実行した後、M.xはまだ20です。それはどのように可能ですか?

7
Barty

まず、joinを使用します。これは、プロセスが終了するのを待ってから、残りのコードを続行します。

次に、multiprocessを使用すると、MごとにProcessの新しいインスタンスが作成されます。 self内にloopを印刷するとこれがわかります

class Multi:
    def __init__(self):
        self.x = 20

    def loop(self):
        print(self, 'loop')
        for i in range(1, 100):
            self.x = i


if __name__ == '__main__':
    M = Multi()
    print(M, 'main 1')
    p = Process(target=M.loop)
    p.start()
    p.join()
    print(M, 'main 2')

>>> <__main__.Multi object at 0x000001E19015CCC0> main 1
>>> <__mp_main__.Multi object at 0x00000246B3614E10> loop
>>> <__main__.Multi object at 0x000001E19015CCC0> main 2

そのため、xの値が元のクラスで更新されることはありません。

幸い、これを処理するために使用できる Value オブジェクトがあります。これにより、プロセスを通じて変更できる共有メモリオブジェクトが作成されます

from multiprocessing import Process, Value


class Multi:
    def __init__(self):
        self.x = Value('i', 20)

    def loop(self):
        for i in range(1, 100):
            self.x.value = i


if __name__ == '__main__':
    M = Multi()
    p = Process(target=M.loop)
    p.start()
    p.join()

    print(int(M.x.value))
    >> 99
11
Wondercricket

この問題は、_M.x_の値をチェックしているときに、ループが実際に実行されるのはbeforeであるという事実が原因である可能性があります(マルチプロセッシングの並列性のため)。 loop()の中にprintステートメントを置き、p.start()の後に1つ入れて、_M.x_を出力してみてください。どちらが最初に印刷されるかを確認してください。おそらく_M.x_のものです。

1
MLavrentyev
from multiprocessing import Process

class Multi:
    def __init__(self):
        self.x = 20


    def loop(self):
        for i in range(1,100):
            self.x = i
        print self.x


M = Multi()

p = Process(target=M.loop, args = ())
p.start()

これは、loopメソッド内にprintステートメントを含むコードです。

0
Barty