嗯,我正在嘗試爲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