Python Twisted 和 callInThread
我把我的应用程序简化了一下,但这应该能给你一个我在做什么的例子。
def run_app(f):
p = Popen(['/usr/bin/app'],stdout=PIPE)
while True:
o = p.stdout.readline()
if o == '' and p.poll() != None: break
reactor.callFromThread(f, o)
class Echo(Protocol):
def connectionMade(self):
reactor.callInThread(run_app, self.appDataReceived)
def dataReceived(self, data):
data = data.strip()
if data == "getmore":
print "getmore"
def appDataReceived(self, u):
print u
def main():
factory = Factory()
factory.protocol = Echo
reactor.listenTCP(3646, factory)
reactor.run()
if __name__ == "__main__":
main()
我有一个应用程序,我想让它连接并运行一个不断向标准输出(stdout)输出数据的程序。现在我的应用程序可以正常工作,但问题是,当客户端退出套接字连接时,/usr/bin/app 仍然在继续运行。连接的套接字越多,这个程序就会越多地在运行。
有没有办法通过 Echo Procool 来结束 run_app() 这个函数的运行呢?
2 个回答
3
不要使用线程和 Popen。建议使用 Twisted 的进程支持。另外,你的 Echo
协议 需要进行分帧,否则无法保证它会收到 "getmore"
这个字符串。
1
我有几个建议,希望能帮你解决问题。
不要使用 reactor.callFromThread,应该用 deferToThread。
from twisted.internet.threads import deferToThread
deferredObj = threads.deferToThread(run_app, self.appDataReceived)
就像你在连接建立时启动线程一样,当连接断开时也需要采取行动。
示例代码:
class Echo(Protocol):
def connectionLost(self, reason):
print reason
# which is crude, there should be a more elegant answer
reactor.stop()
确实,deferToThread 更适合处理短时间运行的任务。实际上,最好重新设计你的代码,让线程只负责运行这个过程并返回结果。