如何在扭曲的python中获取spawn进程的状态?

时间:2013-08-07 13:09:56

标签: python process twisted spawn

我想要不断触发许多长时间运行的进程。并且,根据执行的每个进程返回的状态,我需要执行其他任务。在下面的示例中,我能够生成进程,但是我无法捕获/获取返回到邮件循环的生成进程执行状态的详细信息(即在CmdProtocol类中)。

我对这个扭曲的蟒蛇概念不熟悉 - 有人可以帮助我吗?

import sys
from twisted.internet.protocol import ServerFactory, ProcessProtocol
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor
from twisted.internet import protocol
import os
import signal


class MyPP(protocol.ProcessProtocol):
    def __init__(self):
        self.parent_id = os.getpid()

    def connectionMade(self):
        print "connectionMade!"
        print "Parent id = %s" % self.parent_id
        print "Child process id = %s" % self.transport.pid

    def outReceived(self, data):
        print "out", data

    def errReceived(self, data):
        print "error", data

    def inConnectionLost(self):
        print "inConnectionLost! stdin is closed! (we probably did it)"
        print "Parent id = %s" % self.parent_id
        print "Child process id closes STDIN= %s" % self.transport.pid    

    def outConnectionLost(self):
        print "outConnectionLost! The child closed their stdout!"
        print "Parent id = %s" % self.parent_id
        print "Child process id closes STDOUT = %s" % self.transport.pid                

    def errConnectionLost(self):
        print "errConnectionLost! The child closed their stderr."
        print "Parent id = %s" % self.parent_id
        print "Child process id closes ERRCONN = %s" % self.transport.pid    

    def processExited(self, reason):
        print "processExited %s, status %d" % (self.transport.pid, reason.value.exitCode,)

    def processEnded(self, reason):
        print "%s processEnded, status %d" % (self.transport.pid, reason.value.exitCode,)
        print "quitting"

class CmdProtocol(LineReceiver):

    delimiter = '\n'
    def connectionMade(self):
        self.client_ip = self.transport.getPeer()
        print "Client connection from %s" % self.client_ip

    def processcmd(self):
        pp = MyPP()
        cmd = ['c:\Python27\python.exe', '-u',  'print_hi.py']
        print "Calling processcmd - <%s>" % cmd
        reactor.spawnProcess(pp, cmd[0], cmd[1:])

    def connectionLost(self, reason):
        print "Lost client connection.  Reason: %s" % reason

    def lineReceived(self, line):
        if not line: return
        # Parse the command
        print 'Cmd received from %s : %s' % (self.client_ip, line)
        commandParts = line.split()

        if len(commandParts) > 0:
            command = commandParts[0].lower()
            args = commandParts[1:]
            try:
                print "Command received : <%s>" % command
                method = getattr(self, command)
            except AttributeError, e:
                self.sendLine('Error: no such command.')
            else:
                try:
                    res = method()
                    print "Returned status:%s" % res
                    self.sendLine('Command executed successfully.')                
                except Exception, e:
                    self.sendLine('Error: ' + str(e))     

    def do_kill(self, pid):
        """kill: Kill a process (PID)"""
        print 'Killing pid:%s' % pid
        res = os.kill(int(pid), signal.SIGTERM)
        print "Kill Status %s" % res

class MyFactory(ServerFactory):
    protocol = CmdProtocol
    def __init__(self):
        print "Factory called"

reactor.listenTCP(8000, MyFactory())
reactor.run()

1 个答案:

答案 0 :(得分:1)

这实际上是一个非常基本的Python数据结构问题。您只需要从CmdProtocol的实例引用MyPP的实例。由于CmdProtocol首先构建MyPP,因此这很容易。只需将MyPP的结构更改为如下所示:

def processcmd(self):
    pp = MyPP(self)

然后MyPP.__init__看起来像这样:

def __init__(self, cmd_protocol):
    self.parent_id = os.getpid()
    self.cmd_protocol = cmd_protocol

然后,在MyPP上的任何方法中,您都可以使用CmdProtocol访问相关的self.cmd_protocol实例。