在twisted中使用我自己的主循环

2024-09-30 04:37:19 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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


Tags: 函数run用户程序远程顺序twisted情况
2条回答

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

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

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

您也可以使用threadedselectreactor编写一个最小的reactor。这方面的文档也很少,但是the wxpython reactor是使用它实现的。就我个人而言,我不推荐这种方法,因为它很难测试并且可能会导致混乱的竞争条件,但是它确实有一个优点,可以让您利用Twisted的所有默认网络代码,只需一层薄薄的包装。在

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

  • 在主循环启动之前在另一个线程中开始Twisted,使用类似twistedThread = Thread(target=reactor.run); twistedThread.start()
  • 在你自己的主循环线程中实例化一个对象来进行RPC通信(比如,RPCDoer),这样你就有了对它的引用。请确保使用^{}启动它的Twisted逻辑,这样就不需要包装它所有的Twisted API调用。在
  • 实现RPCDoer.doRPC以返回一个Deferred,只使用扭曲的API调用(即,不要调用现有的应用程序代码,因此您不必担心应用程序对象的线程安全;将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 loop已经过数百万用户的广泛测试,并在各种各样的环境中使用。如果您的循环也非常成熟,这可能不是什么大问题,但是如果您正在编写一个小的、新的程序,那么可靠性的差异可能会非常大。在

似乎正确而简单的答案是一个循环调用:

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()

相关问题 更多 >

    热门问题