简体   繁体   English

每N秒调用2个python函数

[英]Call 2 python functions every N seconds

In my .py script I have 2 functions. 在我的.py脚本中,我有2个功能。 One of them should be called every 5 minutes , and the other should be called every 4 hours . 其中每5分钟应调用一次,另一方应每4小时调用一次。 The second one, however, only runs once when the script is ran and never again (while the 5 minute function works fine). 但是,第二个脚本仅在脚本运行时运行一次,而不会再次运行(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()

This is the whole code, I'm running it on Linux(Raspberry Pi) 这是完整的代码,我正在Linux(Raspberry Pi)上运行它

PS I think that the problem could be that 4_h function is interrupted by 5_min function. PS我认为问题可能出在4_h函数被5_min函数中断。

Your four_hour function may be raising an exception before threading.Timer().start() is called again: 您的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()

yields 产量

[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
...

(Note: I changed the delays so the script is easier to test. Once you are satisfied with the script's qualitative behaviour, you can the delays as you desire.) (注意:我更改了延迟,因此脚本更易于测试。一旦您对脚本的定性行为感到满意,就可以根据需要设置延迟。)


Note: as clemtoy points out , as long as there is no need for inter-thread or inter-process communication, it may be easier to use cron to call separate scripts which run the five_min and four_hour functions. 注意: 正如clemtoy所指出的 ,只要不需要线程间或进程间通信, 使用cron调用运行five_minfour_hour函数的单独脚本可能会更容易。 If you do need inter-process communication, it may still be better to use cron, but you'd have to structure your code differently, perhaps reading from a database to learn the state of erstwhile global variables. 如果确实需要进程间通信,那么使用cron可能仍然更好,但是您必须以不同的方式构造代码,也许从数据库中读取以了解以前的全局变量的状态。

I also believe the problem is that 4_h() is interrupted by the other function. 我也相信问题是4_h()被另一个函数中断了。 You could create a counter var inside 5_min and call 4_h() from there. 您可以在5_min内创建一个计数器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():
    ...

It is probably not the best solution, but is the best one I know. 它可能不是最好的解决方案,但我知道是最好的解决方案。

In my view, the best way to plan tasks on linux is to use cron . 我认为,在Linux上计划任务的最佳方法是使用cron If you want your script to add the task itself to the linux crontab, you should look at the python-crontab package. 如果您希望脚本将任务本身添加到linux crontab中,则应查看python-crontab软件包。

Aside the syntax now. 现在放下语法。 I would suggest you doing it this way: 我建议您这样做:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM