在<finalize object,=“”dead =“”>中绑定信号处理程序时没有属性'_popen'“</finalize>

时间:2013-12-30 14:01:56

标签: python signals warnings multiprocessing

每当子类化mulitprocessing.Process类并将SIGCHLD信号绑定到其中时,python解释器会引发以下错误:

Exception AttributeError: "'MyClass' object has no attribute '_popen'" in <Finalize object, dead> ignored

但我的班级却有预期的行为。

以下是信号处理的样子:

import os 
import signal
import multiprocessing

class Actor(multiprocessing.Process):
    def __init__(self, *args, **kwargs):
        self.bind_signals_handlers()
        ...
        super(Actor, self).__init__(*args, **kwargs)

    def on_children_exit(self):
        """Signal handler to be called on SIGCHLD.

        This handler will be called on every SIGCHLD signal received
        by the actor. SIGCHLD is raised on process interuptions and on
        process death, so you can override this handler to set up
        the behavior you'd like.

        As a default this handler will check if a child process
        as exited, and that's it.
        """
        # Make sure we do the waitpid over the parent process
        # and not from any children.
        # see http://stackoverflow.com/questions/5783183/python-multiprocessing-issue-misunderstanding
        # see http://bugs.python.org/issue9535
        if os.getpid() == self.pid:
            pid, status = os.waitpid(-1, os.WNOHANG)
            if pid:
                print "Actor's child with pid {} exited".format(pid)

    def bind_signals_handlers(self):
        def sig_child_handler(signum, frame):
            self.on_children_exit()
        def sig_shutdown_handler(signum, frame):
            self.stop()

        signal.signal(signal.SIGTERM, sig_shutdown_handler)
        signal.signal(signal.SIGINT, sig_shutdown_handler)
        signal.signal(signal.SIGCHLD, sig_child_handler)

知道是什么导致了警告,以及如何解决它?

非常感谢!

2 个答案:

答案 0 :(得分:3)

我终于通过捕获AttributeError并检查回溯来找到解决方案。碰巧在pid实例启动之前访问multiprocessing.Process属性会引发AttributeError

我没有找到任何关于它的文档。

答案 1 :(得分:1)

我在研究类似异常时遇到了这个问题:

File "/usr/local/Cellar/python/3.6.5_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/process.py", line 99, in start
    assert self._popen is None, 'cannot start a process twice'
AttributeError: 'MyProcess' object has no attribute '_popen'

在我的情况下,问题的根源是我忘记在适当的地方调用Process的构造函数:

class MyProcess(multiprocessing.Process):

    def __init__(self, settings):
        super(MyProcess, self).__init__() # Don't forget this!
        ...

很明显,该调用存在于原始问题中,但是由于它是在子类构造函数的末尾调用的,因此如果这是原因,我将不会感到惊讶(尽管我不确定是否移动调用是在这种情况下的适当补救措施。