扭曲:如何在反应堆代码和线程代码之间优雅地通信?

2024-10-01 17:27:44 发布

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

我有一个客户端使用twisted连接到服务器。客户端有一个线程,它可能在后台执行某些操作。当反应堆关闭时,我必须:

1) check if the thread is doing things
2) stop it if it is

什么是一个优雅的方式来做这个?我能做的最好的事情就是:

^{pr2}$

首先我们检查它是否有效。该回调的结果进入rescallback,该函数要么关闭要么不关闭,然后激发doneDF,该函数twisted等待直到关闭。在

真是一团糟啊!有更好的方法吗?在

也许一个相关的问题是,有没有一种更优雅的方式来将回调链接到彼此?我可以看到我自己在这之后需要做更多的清理代码,所以我必须做一个不同的done延迟,并让当前的doneDF触发一个回调函数,该回调函数执行一些操作,然后调用done延迟的操作。。在


Tags: the函数服务器客户端ifischeck方式
3条回答

如果程序在你关闭反应器后终止,你可以让线程成为守护进程线程。当所有非守护进程线程终止时,这将自动退出。在调用start()之前,只需在thread对象上设置daemon = True。在

如果这是不可行的,例如,线程必须在退出之前进行资源清理,那么您可以使用队列在reactor和线程之间进行通信。将要完成的工作推送到队列对象上,并让线程将其拔出并执行。有一个特殊的“FINISH”标记(或者干脆没有)来指示线程需要终止。在

您可以使用deferToThread而不是callInThread/callFromThread对来简化这一点:

from twisted.internet.threads import deferToThread

def cleanup(self):
    isWorkingDF = deferToThread(self.stuff.isWorking)

    def shutdownOrNot(isWorking):
        if isWorking:
            #shutdown necessary, shutdown is also a blocking call
            return deferToThread(self.stuff.shutdown)

    isWorkingDF.addCallback(shutdownOrNot)

    return isWorkingDF

deferToThread基本上只是一个很好的包装器,围绕着在函数版本中实现了两次的同一线程逻辑。在

啊,真正的答案是使用defer.inlineCallbacks修饰符。以上代码现在变成:

@defer.inlineCallbacks
def procShutdownStuff(self):
    isWorking = yield deferToThread(self.stuff.isWorking)

    if isWorking:
        yield deferToThread(self.stuff.shutdown)

def cleanup(self):
    return self.procShutdownStuff()

相关问题 更多 >

    热门问题