每 N 秒调用 2 python 个函数

Call 2 python functions every N seconds

在我的 .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 函数打断了。

我也认为问题在于 4_h() 被其他函数中断了。您可以在 5_min 中创建一个计数器变量,然后从那里调用 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():
    ...

这可能不是最好的解决方案,但却是我所知道的最好的解决方案。

您的 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
...

(注意:我更改了延迟,以便脚本更容易测试。一旦你 对脚本的定性行为感到满意,您可以延迟 愿望。)


注:,如 只要不需要线程间或进程间通信,它就可以 更容易 使用 cron 调用 运行 five_minfour_hour 函数的独立脚本。如果你这样做 需要进程间通信,使用 cron 可能仍然更好,但你会 必须以不同的方式构建代码,也许从数据库读取到 了解以前全局变量的状态。

在我看来,在 linux 上计划任务的最佳方法是使用 cron. If you want your script to add the task itself to the linux crontab, you should look at the python-crontab 包。

现在抛开语法。 我建议你这样做:

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