【问题标题】:Twisted callRemote扭曲呼叫远程
【发布时间】:2016-05-06 14:45:48
【问题描述】:

我必须进行可能需要很长时间(超过 60 秒)的远程呼叫。我们的整个代码依赖于处理 callRemote 的返回值,所以这很糟糕,因为尽管使用了 twqisted + 50 个工作线程运行,但我们一直在阻塞 IO。

我们目前使用类似的东西

result = threads.blockingCallFromThread(reactor, callRemote, "method", args)

然后得到结果/继续,但正如它的名字所说,它阻塞了事件循环,所以我们不能同时等待多个结果。

我无法重构整个代码以使其异步,所以我认为唯一的方法是将长 IO 任务推迟到线程。

我正在尝试在线程中进行远程调用,但我找不到从阻塞调用返回结果的方法。进行了 remoteCalls,结果在某个地方,但我无法抓住它。

我目前正在尝试做的事情看起来像

reactor.callInThread(callRemote, name, *args, **kw)

它返回一个空的 Deferred(为什么?)。

我正在尝试将结果放入某种队列中,但它不起作用。我该怎么做?

【问题讨论】:

    标签: python multithreading asynchronous twisted


    【解决方案1】:

    AFAIK,blockingCallFromThread 在reactor 的线程中执行代码。这就是为什么它不能按您的需要工作。

    如果我理解正确,您需要将一些操作移出reactors 线程并将结果放入reactors 线程。

    对于相同的情况,我使用 deferToThread 的方法。 延迟示例:

    import time
    from twisted.internet import reactor, threads
    
    def doLongCalculation():
        time.sleep(1)
        return 3
    
    def printResult(x):
        print x
    
    # run method in thread and get result as defer.Deferred
    d = threads.deferToThread(doLongCalculation)
    d.addCallback(printResult)
    reactor.run()
    

    另外,您可能对threads.deferToThreadPool 感兴趣。

    Documentation about threading in Twisted.

    【讨论】:

    • 感谢您的回答,但实际上我已经尝试过这一点以及其他一些事情,我得到了 Deferred 回复(即它打印 '),而不是结果当我做一个blockingCallFromThread时我得到了。任何想法 ?我想这与嵌套延迟有关,但我找不到强制内部延迟触发的方法。
    • 我也试过 reactor.callInThread 也不起作用,我想知道 reactor.callInThread 和 threads.deferToThread 有什么区别?
    • 关于嵌套延迟,我的建议是尽可能使用@defer.inlineCallback 重构您的代码。我刚刚查看了blockingCallFromThreadtwistedmatrix.com/trac/browser/tags/releases/twisted-16.0.0/… 的来源。该代码使用Queue.Queue 存储回调和errback 的结果。我的第二条建议:尝试模仿blockingCallFromThread 并使用Queue 进行处理,但使用callInThread 将计算移至单独的线程。
    • 注意,reactor.callInThread 和threads.deferToThread 之间的主要区别在于最后一个返回结果为开箱即用的延迟。顺便说一句,threads.deferToThread 使用 reactor.callFromThread。
    • 好吧,我知道了。确实有一个嵌套回调;如果我选择res = threads.deferToThread(callRemote, method, *args, **kw),它会将 res 作为延迟返回。一段时间后(最多 60 秒)延迟触发,我可以在 res.result.result 中得到它的结果。我不知道如何以非阻塞方式等待结果。我在一个单独的线程中启动了某种“轮询”过程,它每 x 秒检查一次延迟是否已触发,但由于某种原因,应用程序在等待过程中阻塞。
    猜你喜欢
    • 1970-01-01
    • 2012-10-19
    • 2013-11-07
    • 2012-03-11
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    相关资源
    最近更新 更多