好吧,正如扭曲的文档所说:
延迟不会使代码神奇地无法阻止
每当使用阻塞代码(例如)时
sleep,都必须将其推迟到新线程。
#!/usr/bin/env pythonfrom twisted.internet import reactor,defer, threadsfrom twisted.internet.task import LoopingCallimport timedef main_loop(): print 'doing stuff in main loop.. do not block me!'def aBlockingRedisCall(x): if x<5: #all connections are busy, try later print '%s is less than 5, get a redis client later' % x x+=1 d = defer.Deferred() d.addCallback(aBlockingRedisCall) reactor.callLater(1.0,d.callback,x) return d else: print 'got a redis client; doing lookup.. this may take a while' def getstuff( x ): time.sleep(3) return "stuff is %s" % x # getstuff is blocking, so you need to push it to a new thread d = threads.deferToThread(getstuff, x) d.addCallback(gotFinalResult) return ddef gotFinalResult(x): return 'final result is %s' % xdef result(res): print resdef aBlockingMethod(): print 'going to sleep...' time.sleep(10) print 'woke up'def main(): lc = LoopingCall(main_loop) lc.start(2) d = defer.Deferred() d.addCallback(aBlockingRedisCall) d.addCallback(result) reactor.callInThread(d.callback, 1) reactor.run()if __name__=='__main__': main()
如果redis api不太复杂,则可以使用twisted.web重写它,而不是仅在很多线程中调用阻塞的api,这样会更自然。



