2011-08-27 65 views
3

我有一个简单的例子:如何在线程中使用LoopingCall?

from twisted.internet import utils, reactor 
from twisted.internet import defer 
from twisted.internet import threads 
from twisted.internet.task import LoopingCall,deferLater 
import time 

def test1(): 
    print 'test' 

def test2(res): 
     l = [] 
     for i in xrange(3): 
      l.append(threads.deferToThread(test4)) 
     return defer.DeferredList(l) 

def test3(res): 
    pass 

def test4(): 
    print 'thread start' 
    time.sleep(10) 
    print 'thread stop' 


def loop(): 
    d = defer.maybeDeferred(test1) 
    d = d.addCallback(test2) 
    d.addCallback(test3) 

LoopingCall(loop).start(2) 

reactor.run() 

它的脚本不正确的工作。我想:

1) print 'test' 
2) start 3 threads, waiting while all threads stops 
3) sleep 2 seconds 
4) repeat 

回答

5

LoopingCall将运行传递到它的每N秒可调用的,其中N是你传递给启动次数。在上一次呼叫结束后,它不会等待N秒,而是在上次呼叫开始后等待N秒。换句话说,它试图停留在由N和起始时间定义的间隔上,以N秒,N * 2秒,N * 3秒等等运行呼叫。

如果进程太忙做出其中一个呼叫,它将跳过该迭代。如果调用返回Deferred并且Deferred在下一个时间间隔内未触发,则它将跳过该迭代。

所以,你可以通过在loop结束返回d接近你想要的行为,但LoopingCall不会总是等待2秒延迟闪光后。它将等待N秒的下一个倍数,从开始时间开始计数,然后再次调用该函数。