代码之家  ›  专栏  ›  技术社区  ›  Ross Rogers

在Python中,如何将线程置于睡眠状态,直到特定的时间?

  •  32
  • Ross Rogers  · 技术社区  · 15 年前

    我知道我可以使线程在特定的时间内休眠:

    time.sleep(NUM)
    

    我怎么能睡到凌晨2点?我需要做数学计算来确定凌晨2点之前的秒数吗?或者有图书馆的功能吗?

    (是的,我知道Windows中的cron和等效系统,但我想让线程在python中正常休眠,而不依赖外部刺激或进程信号。)

    7 回复  |  直到 5 年前
        1
  •  34
  •   Ross Rogers    11 年前

    这里有一个不考虑时钟抖动或时钟调整的半屁股解决方案。请参阅注释以了解如何消除这些问题。

    import time
    import datetime
    
    # if for some reason this script is still running
    # after a year, we'll stop after 365 days
    for i in xrange(0,365):
        # sleep until 2AM
        t = datetime.datetime.today()
        future = datetime.datetime(t.year,t.month,t.day,2,0)
        if t.hour >= 2:
            future += datetime.timedelta(days=1)
        time.sleep((future-t).seconds)
    
        # do 2AM stuff
    
        2
  •  19
  •   Bobby Zandavi    9 年前
    import pause
    from datetime import datetime
    
    pause.until(datetime(2015, 8, 12, 2))
    
        3
  •  4
  •   carl    15 年前

    一种可能的方法是睡一个小时。每小时,检查时间是否在午夜。如果是,继续您的操作。如果没有,再睡一个小时,然后继续。

    如果用户要在中午更改时钟,这种方法将反映出这种更改。虽然它需要更多的资源,但应该忽略不计。

        4
  •  3
  •   MZA    9 年前

    我试过“暂停”打包。它不适用于python 3.x。我从pause包中提取了等待特定日期时间所需的代码,并进行了以下定义。

    def wait_until(execute_it_now):
        while True:
            diff = (execute_it_now - datetime.now()).total_seconds()
            if diff <= 0:
                return
            elif diff <= 0.1:
                time.sleep(0.001)
            elif diff <= 0.5:
                time.sleep(0.01)
            elif diff <= 1.5:
                time.sleep(0.1)
            else:
                time.sleep(1)
    
        5
  •  2
  •   Krenair raganwald    8 年前

    稍微偏离了原始问题的要点:

    即使您不想和crontabs混在一起,如果您可以将python脚本调度到那些主机上,您可能会对调度anacron任务感兴趣?Anacron与Cron的主要区别在于它不依赖计算机连续运行。根据系统配置的不同,您可能需要管理员权限,即使对于此类用户计划的任务也是如此。

    一个类似的,更现代的工具是由Ubuntu人提供的新贵: http://upstart.ubuntu.com/ 这甚至还没有所需的功能。但是,调度作业和替换Anacron是一个有计划的功能。由于作为Ubuntu的默认initd替换,它具有相当大的吸引力。(我不属于该项目)

    当然,对于已经提供的答案,您可以将相同的功能编码到您的python脚本中,并且它可能更适合您的情况。

    不过,对于其他人来说,anacron或类似的现有系统可能是更好的解决方案。Anacron预安装在许多当前的Linux发行版上(Windows用户存在可移植性问题)。

    维基百科提供了一个指针页面: https://en.wikipedia.org/wiki/Anacron

    如果您使用的是Python版本,那么我将查看异步方面,并确保脚本能够工作,即使时间发生了变化(夏时制等),正如其他人已经评论过的那样。与其等到预先计算好的未来,我总是最多等一个小时,然后再检查时间。即使在移动嵌入式系统上,所投资的计算周期也应该可以忽略不计。

        6
  •  0
  •   onetyone    5 年前

    另一种方法,使用 sleep ,以对数方式减少超时。

    def wait_until(end_datetime):
        while True:
            diff = (end_datetime - datetime.now()).total_seconds()
            if diff < 0: return       # In case end_datetime was in past to begin with
            time.sleep(diff/2)
            if diff <= 0.1: return
    

    基于@mza的答案和@mads y的评论

        7
  •  -2
  •   Tomer    10 年前
    from datetime import datetime
    import time, operator
    time.sleep([i[0]*3600 + i[1]*60 for i in [[H, M]]][0] - [i[0]*3600 + i[1]*60 for i in [map(int, datetime.now().strftime("%H:%M").split(':'))]][0])