2

私のpythonプログラムが正しく処理するための制限であると思われるいくつかの問題が発生しています。私のプログラムは、Ctrl-Cを押した直後にBaseManagerの登録済みクラスのメソッドを呼び出すことができませんでした。継承するクラスとして実装された他のプロセスであってもmultiprocessing.Process から影響を受けます。Ctrl-C の後に正しく実行されないプロセスから呼び出したいメソッドがいくつかあります。

たとえば、次のコードは、Ctrl-C の後に TestClass の mt インスタンスを呼び出すことができません。

from multiprocessing.managers import BaseManager, NamespaceProxy
import time

class TestClass(object):
    def __init__(self, a):
        self.a = a

    def b(self):
        print self.a

class MyManager(BaseManager): pass

class TestProxy(NamespaceProxy):
    # We need to expose the same __dunder__ methods as NamespaceProxy,
    # in addition to the b method.
    _exposed_ = ('__getattribute__', '__setattr__', '__delattr__', 'b')

    def b(self):
        callmethod = object.__getattribute__(self, '_callmethod')
        return callmethod('b')

MyManager.register('TestClass', TestClass, TestProxy)

if __name__ == '__main__':
    manager = MyManager()
    manager.start()
    t = TestClass(1)
    print t.a
    mt = manager.TestClass(2)
    print mt.a
    mt.a = 5
    mt.b()

    try:
        while 1:
            pass
    except (KeyboardInterrupt, SystemExit):
        time.sleep(0.1)
        mt.a = 7
        mt.b()
        print "bye"
        pass

Here is the console output

1
2
5
^CTraceback (most recent call last):
  File "testManager.py", line 38, in <module>
    mt.a = 7
  File "/usr/lib/python2.7/multiprocessing/managers.py", line 1028, in __setattr__
    return callmethod('__setattr__', (key, value))
  File "/usr/lib/python2.7/multiprocessing/managers.py", line 758, in _callmethod
    conn.send((self._id, methodname, args, kwds))
IOError: [Errno 32] Broken pipe

何か提案はありますか?私のコードに回避策や何か問題がありますか?

前もって感謝します。

4

2 に答える 2

1

誰かがこの問題を抱えていた場合、この回答https://stackoverflow.com/a/21106459/1667319に基づいて解決しました。これが作業コードです

from multiprocessing.managers import SyncManager, NamespaceProxy
import time
import signal

#handle SIGINT from SyncManager object
def mgr_sig_handler(signal, frame):
    print 'not closing the mgr'

#initilizer for SyncManager
def mgr_init():
    signal.signal(signal.SIGINT, mgr_sig_handler)
    #signal.signal(signal.SIGINT, signal.SIG_IGN) # <- OR do this to just ignore the signal
    print 'initialized mananger'

class TestClass(object):
    def __init__(self, a):
        self.a = a

    def b(self):
        print self.a

class MyManager(SyncManager): pass

class TestProxy(NamespaceProxy):
    # We need to expose the same __dunder__ methods as NamespaceProxy,
    # in addition to the b method.
    _exposed_ = ('__getattribute__', '__setattr__', '__delattr__', 'b')

    def b(self):
        callmethod = object.__getattribute__(self, '_callmethod')
        return callmethod('b')

MyManager.register('TestClass', TestClass, TestProxy)

if __name__ == '__main__':
    manager = MyManager()
    manager.start(mgr_init)
    t = TestClass(1)
    print t.a
    mt = manager.TestClass(2)
    print mt.a
    mt.a = 5
    mt.b()
    try:
        while 1:
            pass
    except (KeyboardInterrupt, SystemExit):
        time.sleep(0.1)
        mt.a = 7
        mt.b()
        print "bye"
        pass

乾杯、

于 2016-05-06T16:27:46.850 に答える