在我的.py脚本中,我有2个功能。其中一个应该每隔 5分钟调用一次,另一个应该每 4小时调用。然而,第二个只在脚本运行时运行一次而不再运行(而5分钟功能正常工作)。
#!/usr/bin/env python
import threading
def five_min():
threading.Timer(300, five_min).start()
print("5 min")
def four_h():
threading.Timer(14400, four_h).start()
print("4 h")
five_min()
four_h()
这是整个代码,我在Linux(Raspberry Pi)上运行它
P.S。 我认为问题可能是4_h函数被5_min函数中断。
答案 0 :(得分:2)
在再次调用 four_hour
之前,您的threading.Timer().start()
函数可能会引发异常:
import threading
import logging
logger = logging.getLogger(__name__)
def five_min():
t = threading.Timer(5, five_min).start()
logger.info("5 min")
def four_hour():
1/0 # <-- Raise an exception
threading.Timer(4, four_hour).start()
logger.info("4 h")
logging.basicConfig(level=logging.DEBUG,
format='[%(asctime)s %(threadName)s] %(message)s',
datefmt='%M:%S')
five_min()
four_hour()
产量
[57:54 MainThread] 5 min
Traceback (most recent call last):
File "script.py", line 21, in <module>
four_hour()
File "script.py", line 12, in four_hour
1/0
ZeroDivisionError: integer division or modulo by zero
[57:59 Thread-1] 5 min
[58:04 Thread-2] 5 min
...
(注意:我更改了延迟,因此脚本更容易测试。一旦你 对脚本的定性行为感到满意,你可以像你一样延迟 欲望。)
注意:as clemtoy points out,如
只要不需要进行线程间或进程间通信,它就可以
更容易use
cron致电
运行five_min
和four_hour
函数的单独脚本。如果你这样做
需要进程间通信,使用cron可能仍然更好,但是你可以
必须以不同的方式构建代码,也许从数据库中读取
了解以前的全局变量的状态。
答案 1 :(得分:0)
我也相信问题是 4_h()被另一个函数打断了。您可以在 5_min 中创建一个counter var,然后从那里调用4_h()。
#!/usr/bin/env python
import threading
counter = 0
def 5_min():
threading.Timer(300, 5_min).start()
counter += 1
if (counter == 48):
counter = 0
4_h()
print("5 min")
def 4_h():
...
这可能不是最好的解决方案,但却是我所知道的最佳解决方案。
答案 2 :(得分:0)
在我看来,在linux上规划任务的最佳方法是使用cron。如果您希望脚本将任务本身添加到linux crontab,您应该查看python-crontab包。
答案 3 :(得分:0)
现在除了语法。 我建议你这样做:
from threading import Timer
s = 0; m = 0
fivesec_timer = None
fourmin_timer = None
def fivesec ():
global fivesec_timer, s
print s, "seconds passed after start"
s += 5
fivesec_timer = Timer(5, fivesec)
fivesec_timer.start()
def fourmin ():
global fourmin_timer, m
print m, "minutes passed after start"
m += 4
fourmin_timer = Timer(4*60, fourmin)
fourmin_timer.start()
fivesec()
fourmin()
# Here some code and blocking code
# For instance:
raw_input()
fivesec_timer.cancel()
fourmin_timer.cancel()
This way, you can control your timers outside your functions.
Don't do Timer(...).start(), especialy not inside a function (local scope).
It should work fine, but you never know what and when garbage collector would clean up or something else occurs. You do not know how the _Timer() is implemented internally.
And you don't have a hard reference to the timer (in a var) all the time.
Mutual canceling out was probably caused by that, although this is clear speculation.
threading module is well tested, yet you experienced problems. Keep your code neat. Best to be sure.
Well, that is my view of the world. Someone will not agree. :D