嗯,我正在尝试为Blender编写一个附加组件,并且我需要每n秒执行一次,但是,我无法使用while循环,因为它冻结了Blender!我该怎么办?每隔n秒做一次没有while循环的事情?
回答
从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
这真的好像工作... – Antoni4040
import threading
def hello():
print "hello, world"
t = threading.Timer(30.0, hello)
t.start() # after 30 seconds, "hello, world" will be printed
我不是很好用蟒蛇,并没有试过这个。看看这可以帮助您:)
@hayden这不正确。将'threading.activeCount()'添加到'print'语句中,可以看到至多有3个正在运行的线程(在't.start()'之前2个)和3个之后):父节点(之前的'hello'),一个正在执行(当前'hello'),另一个正在生成('t.start')。这个代码的问题是你不能跳出定时器循环,迫使用户从外部终止进程。 –
@ Nisan.H这仍然是一个问题...... –
那么,在每一步添加一个线程安全变量的条件检查以确定循环是否应该停止并不是很困难。这是一个非常基本的计时器,我通常会避免以特定的形式使用它,而不是使用比单功能无限循环更复杂的东西,但它确实有效。当然,在没有线程的情况下,可以在'while True:...'循环中使用'time.sleep(x)',因为在这个例子中它没有增加任何好处。 –
from threading import Timer
def doSomeThings():
print "Things are being done"
t = Timer(5.0, doSomeThings) # every 5 seconds
t.start()
根据您的需求,time.sleep
或threading.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()
这通常是一次安全的,在这个意义上,因为每次操作一个线程在执行时,主线程仍然可以切换单个操作线程中的阻塞部分,并在其他操作上维护时间表(假设您的函数不会在解释器一直引发任何异常,打破主调度器线程...)
我不知道这将如何与搅拌机,但它的工作在我使用过的其他环境(特别是基于龙卷风的服务器)时,它处于非阻塞模式。
- 1. while循环中每隔n秒刷新一次异步页面
- 2. 在x分钟再做一次事情,然后每隔n分钟做一次
- 3. for或while循环做n次
- 4. 循环做n次没有int i = 0?
- 5. 如何每秒做n次?
- 6. Java while循环跳过行,每2个循环做一次
- 7. 每秒运行while循环
- 8. 每隔n秒复制一次
- 9. 做while循环 - 只有两次循环 - 应循环8次
- 10. 循环没有做任何事情
- 11. 是一个while(true)循环比邮寄handler.postDelayed()每隔X毫秒
- 12. JavaScript - 每n秒做一件事
- 13. 做一个onClick事件,每隔一次点击做一些不同的事情?
- 14. VB.NET while循环调用application.DoEvents每秒一次
- 15. while while循环每次循环重复两次cout行?
- 16. Netlogo while while循环只有一次
- 17. Python:循环做同样的事情到一个项目n次,而不是一次n项目
- 18. 循环每隔一行跳过一次?
- 19. C#在while循环中调用函数每X秒没有阻塞循环
- 20. C++做while循环没有响应
- 21. 每秒运行一次循环sleep_for
- 22. 如何每隔N秒刷新一次网页的一部分
- 23. 第n次迭代wordpress while循环
- 24. 做while循环:在循环内执行一次
- 25. 为什么while循环不能每秒打印1,000次?
- 26. Perl while while循环只在for循环中循环一次
- 27. Angular 2:在其他所有的角度2完成后,如何在while循环中每5秒做一次?
- 28. 暂停while循环,并在Matlab中做别的事情
- 29. 我做while while循环只执行一次
- 30. 做while while循环永远
我不太了解python。但你不能用一个定时器和一个处理程序! – LivingThing
更多详情,请... – Antoni4040
为什么这个问题关闭?如果您使用Blender并且与编程语言直接相关,则这是完全有效的。 – AMACB