扭曲的非阻塞方法 - 怎么做?

2 投票
1 回答
3518 浏览
提问于 2025-04-17 13:07

我的代码是这样的:

... # class Site(Resource)
def render_POST(self,request)
   otherclass.doAssync(request.args)
   print '1'
   return "done" #that returns the HTTP response, always the same.

...

def doAssync(self,msg):
    d = defer.Deferred()
    reactor.callLater(0,self.doStuff,d,msg)
    d.addCallback(self.sucess)

def doStuff(self,d,msg):
    # do some stuff
    time.sleep(2)  #just for example
    d.callback('ok')

def sucess(msg):
    print msg

输出结果是:

1

ok

到目前为止,一切正常。但是,HTTP的响应(返回'done')是在延迟之后才发生的(time.sleep(2))。我能知道这一点,因为浏览器会在加载2秒钟。

我哪里做错了呢?

1 个回答

4

你现在做错的事情是使用了一个会阻塞的调用(time.sleep(2)),而Twisted希望你只进行非阻塞的操作,也就是那些不会让程序停下来的事情。因为你在代码里用了time.sleep(2),所以在这个函数“睡觉”的时候,Twisted就无法做其他事情了,也就无法把数据发送到浏览器。

对于time.sleep(2),你应该用另一个reactor.callLater来替代。如果你其实是想让time.sleep(2)做其他的阻塞操作,那么如何修复这个问题就要看具体的操作了。如果你能用非阻塞的方式来完成这个操作,那就这样做。对于很多这样的操作(比如和数据库的交互),Twisted已经提供了非阻塞的替代方案。如果你正在做的事情没有非阻塞的接口,而Twisted也没有替代方案,那么你可能需要在一个单独的线程中运行这段代码(比如使用twisted.internet.threads.deferToThread),不过这要求你的代码是线程安全的。

撰写回答