扭曲使用我自己的主循环

时间:2010-07-21 20:36:27

标签: python twisted

我有一个现有的程序,它有自己的主循环,并根据它收到的输入进行计算 - 让我们说来自用户,使其变得简单。我想现在远程而不是本地进行计算,我决定在Twisted中实现RPC。

理想情况下,我只想更改我的一个函数,比如doComputation()来调用twisted来执行RPC,获取结果并返回。程序的其余部分应该保持不变。但是我怎么能做到这一点呢?当我呼叫reactor.run()时,Twisted劫持主循环。我还读到你没有扭曲的线程,所有的任务按顺序运行,所以我似乎不能创建一个LoopingCall并以这种方式运行我的主循环。

2 个答案:

答案 0 :(得分:8)

您有几个不同的选项,具体取决于您现有程序的主循环类型。

如果它是GUI库的主循环,Twisted may already have support for it。在这种情况下,您可以继续使用它。

您也可以编写自己的反应堆。没有很多很好的文档,但是you can look at the way that qtreactor在Twisted外部实现了一个reactor插件。

您还可以使用threadedselectreactor编写最小反应堆。此文档也很稀疏,但the wxpython reactor是使用它实现的。我个人不推荐这种方法,因为它很难测试并且可能导致混乱的竞争条件,但它确实具有让你几乎只使用几乎所有Twisted的默认网络代码的优势包裹层。

如果您确定不希望doComputation异步,并希望程序在等待Twisted应答时阻止,请执行以下操作:

  • start在主循环启动之前在另一个线程中扭曲,类似twistedThread = Thread(target=reactor.run); twistedThread.start()
  • 实例化一个对象,在你自己的主循环线程中进行RPC通信(比方说,RPCDoer),这样你就可以引用它了。确保使用reactor.callFromThread实际启动其Twisted逻辑,这样您就不需要包装所有Twisted API调用。
  • 使用Twisted API调用实现RPCDoer.doRPC以返回Deferred(即不要调用现有的应用程序代码,因此您无需担心应用程序对象的线程安全性;将doRPC所需的所有信息作为参数传递。
  • 您现在可以像这样实施doComputation

    def doComputation(self):
        rpcResult = blockingCallFromThread(reactor, self.myRPCDoer.doRPC)
        return self.computeSomethingFrom(rpcResult)
    
  • 请记住从主循环的关闭过程中调用reactor.callFromThread(reactor.stop); twistedThread.join(),否则您可能会在退出时看到一些令人困惑的回溯或日志消息。

最后,你应该考虑一个选项,特别是从长远来看:转储你现有的主循环,找出一种方法来使用Twisted。根据我的经验,对于像这样的问题的10个问题中的9个,这是正确的答案。我并不是说这是始终的方式 - 有很多情况下你真的需要保持自己的主循环,或者只是需要付出过多的努力来摆脱它现有的循环。但是,保持自己的循环也是有效的。请记住,Twisted循环已经被数百万用户广泛测试,并在各种环境中使用。如果你的循环也非常成熟,那可能不是什么大问题,但如果你正在编写一个小的新程序,可靠性的差异可能会很大。

答案 1 :(得分:1)

这里似乎正确且非常简单的答案是LoopingCall:

http://www.saltycrane.com/blog/2008/10/running-functions-periodically-using-twisteds-loopingcall/

from datetime import datetime
from twisted.internet.task import LoopingCall
from twisted.internet import reactor

def doComputation():
    print "Custom fn run at", datetime.now()

lc = LoopingCall(doComputation)
lc.start(0.1)  # run your own loop 10 times a second

# put your other twisted here

reactor.run()