2012-11-01 80 views
3

嗯,我正在尝试为Blender编写一个附加组件,并且我需要每n秒执行一次,但是,我无法使用while循环,因为它冻结了Blender!我该怎么办?每隔n秒做一次没有while循环的事情?

+0

我不太了解python。但你不能用一个定时器和一个处理程序! – LivingThing

+1

更多详情,请... – Antoni4040

+0

为什么这个问题关闭?如果您使用Blender并且与编程语言直接相关,则这是完全有效的。 – AMACB

回答

1

从Blender API文档的Strange errors using ‘threading’ module

Python和Blender的线程,只有当线程完成了脚本执行之前正常工作。例如,使用threading.join()。

注意:Pythons线程只允许使用同币种,并且不会加速多处理器系统上的脚本,子进程和多进程模块可以与搅拌器一起使用,也可以使用多个CPU。

from threading import Thread, Event 

class Repeat(Thread): 
    def __init__(self,delay,function,*args,**kwargs): 
     Thread.__init__(self) 
     self.abort = Event() 
     self.delay = delay 
     self.args = args 
     self.kwargs = kwargs 
     self.function = function 
    def stop(self): 
     self.abort.set() 
    def run(self): 
     while not self.abort.isSet(): 
      self.function(*self.args,**self.kwargs) 
      self.abort.wait(self.delay) 

例子:

from time import sleep 
def do_work(foo): 
    print "busy", foo 
r = Repeat(1,do_work,3.14) # execute do_work(3.14) every second 
r.start() # start the thread 
sleep(5) # let this demo run for 5s 
r.stop() # tell the thread to wake up and stop 
r.join() # don't forget to .join() before your script ends 
+0

这真的好像工作... – Antoni4040

-1
import threading 

def hello(): 
    print "hello, world" 
    t = threading.Timer(30.0, hello) 
    t.start() # after 30 seconds, "hello, world" will be printed 

我不是很好用蟒蛇,并没有试过这个。看看这可以帮助您:)

+0

@hayden这不正确。将'threading.activeCount()'添加到'print'语句中,可以看到至多有3个正在运行的线程(在't.start()'之前2个)和3个之后):父节点(之前的'hello'),一个正在执行(当前'hello'),另一个正在生成('t.start')。这个代码的问题是你不能跳出定时器循环,迫使用户从外部终止进程。 –

+0

@ Nisan.H这仍然是一个问题...... –

+0

那么,在每一步添加一个线程安全变量的条件检查以确定循环是否应该停止并不是很困难。这是一个非常基本的计时器,我通常会避免以特定的形式使用它,而不是使用比单功能无限循环更复杂的东西,但它确实有效。当然,在没有线程的情况下,可以在'while True:...'循环中使用'time.sleep(x)',因为在这个例子中它没有增加任何好处。 –

3
from threading import Timer 

def doSomeThings(): 
    print "Things are being done" 

t = Timer(5.0, doSomeThings) # every 5 seconds 
t.start() 
+0

是的,但我希望它每隔n秒连续完成...... – Antoni4040

+0

值得一提的是你如何阻止它? –

+0

@ Antoni4040用'n'替代'5.0'。 –

1

根据您的需求,time.sleepthreading.Timer可能做的工作。

如果你需要一个更全面的调度,我最喜欢的版本是在http://code.activestate.com/recipes/496800-event-scheduling-threadingtimer/发现配方:

import thread 
import threading 

class Operation(threading._Timer): 
    def __init__(self, *args, **kwargs): 
     threading._Timer.__init__(self, *args, **kwargs) 
     self.setDaemon(True) 

    def run(self): 
     while True: 
      self.finished.clear() 
      self.finished.wait(self.interval) 
      if not self.finished.isSet(): 
       self.function(*self.args, **self.kwargs) 
      else: 
       return 
      self.finished.set() 

class Manager(object): 

    ops = [] 

    def add_operation(self, operation, interval, args=[], kwargs={}): 
     op = Operation(interval, operation, args, kwargs) 
     self.ops.append(op) 
     thread.start_new_thread(op.run,()) 

    def stop(self): 
     for op in self.ops: 
      op.cancel() 

class LockPrint(object): 
    def __init__(self): 
     self.lock = threading.Lock() 
    def lprint(self, value): 
     with self.lock: 
      print value 

if __name__ == '__main__': 
    import time 
    import datetime 

    lp = LockPrint() 

    def hello1(): 
     lp.lprint('{}\thello1!'.format(datetime.datetime.now())) 
    def hello2(): 
     lp.lprint('{}\thello2!'.format(datetime.datetime.now())) 
    def hello3_blocking(): # this is bad, so don't do it in real code ;) 
     lp.lprint('{}\thello3_blocking starting... '.format(
      datetime.datetime.now() 
     )), 
     t = time.time() # get a timestamp 
     x = 0 
     while time.time() - t < 3: # iterate in a blocking loop for 3 secs 
      x += 1 
     lp.lprint('{}\thello3_blocking complete! ({} iterations)'.format(
      datetime.datetime.now(), x 
     )) 



    timer = Manager() 
    timer.add_operation(hello1, 1) 
    timer.add_operation(hello2, 2) 
    timer.add_operation(hello3_blocking, 2) 

    t0 = time.time() 
    while time.time() - t0 < 10: 
     time.sleep(0.1) 
    # turn off everything and exit... 
    timer.stop() 

这通常是一次安全的,在这个意义上,因为每次操作一个线程在执行时,主线程仍然可以切换单个操作线程中的阻塞部分,并在其他操作上维护时间表(假设您的函数不会在解释器一直引发任何异常,打破主调度器线程...)

我不知道这将如何与搅拌机,但它的工作在我使用过的其他环境(特别是基于龙卷风的服务器)时,它处于非阻塞模式。

相关问题