zoukankan      html  css  js  c++  java
  • python 定时任务

    Python 定时任务

    最近学习到了 python 中两种开启定时任务的方法,和大家分享一下心得。

    • sched.scheduler()
    • threading.Timer()

    sched 定时任务

    使用sched的套路如下:

    s = sched.scheduler(time.time, time.sleep)
    s.enter(delay, priority, func1, (arg1, arg2, ...))
    s.enter(delay, priority, func2, (arg1, arg2, arg3, ...))
    s.run()
    

    第一步新建一个调度器;

    第二步添加任务,可以添加多个任务;

    第三步让调度器开始运行。

    第二步各参数含义:

    • delay 相对于调度器添加这个任务时刻的延时,以秒为单位;
    • priority 优先级,数字越小优先级越高;
    • func1 任务函数
    • (arg1, arg2, ...) 任务函数的参数
    import time
    import sched
    
    # 第一个工作函数
    # 第二个参数 @starttime 表示任务开始的时间
    # 很明显参数在建立这个任务的时候就已经传递过去了,至于任务何时开始执行就由调度器决定了
    def worker(msg, starttime):
        print u"任务执行的时刻", time.time(), "传达的消息是", msg, '任务建立时刻', starttime
    
    
    # 创建一个调度器示例
    # 第一参数是获取时间的函数,第二个参数是延时函数
    print u'----------  两个简单的例子  -------------'
    print u'程序启动时刻:', time.time()
    s = sched.scheduler(time.time, time.sleep)
    s.enter(1, 1, worker, ('hello', time.time()))
    s.enter(3, 1, worker, ('world', time.time()))
    s.run()  # 这一个 s.run() 启动上面的两个任务
    print u'睡眠2秒前时刻:', time.time()
    time.sleep(2)
    print u'睡眠2秒结束时刻:', time.time()
    
    
    # 重点关注下面2个任务,建立时间,启动时间
    # 2个任务的建立时间都很好计算,但有没有发现 "hello world [3]" 的启动时间比建立时间晚 13 秒,
    # 这不就是2个 sleep 的总延时吗?所以说启动时间并不一定就是 delay 能指定的,还需要看具体的程序环境,
    # 如果程序堵塞的很厉害,已经浪费了一大段的时间还没有到 scheduler 能调度这个任务,当 scheduler 能调度这个
    # 任务的时候,发现 delay 已经过去了, scheduler 为了弥补“罪过”,会马上启动这个任务。
    
    # 任务 "hello world [15]" 就是一个很好的例子,正常情况下,程序没有阻塞的那么厉害,在scheduler 能调度这个任务的时候
    # 发现 delay 还没到就等待,如果 delay 时间到了就可以在恰好指定的延时调用这个任务。
    print u'\n\n----------  两个复杂的例子  -------------'
    s.enter(3, 1, worker, ('hello world [3]', time.time()))
    print u'睡眠7秒前时刻:', time.time()
    time.sleep(7)
    print u'睡眠7秒结束时刻:', time.time()
    
    
    s.enter(15, 1, worker, ('hello world [15]', time.time()))
    print u'睡眠6秒前时刻:', time.time()
    time.sleep(6)
    print u'睡眠6秒结束时刻:', time.time()
    
    s.run() # 过了2秒之后,启动另外一个任务
    
    
    print u'程序结束时刻', time.time()
    
    ----------  两个简单的例子  -------------
    程序启动时刻: 1481731389.4
    任务执行的时刻 1481731390.4 传达的消息是 hello 任务建立时刻 1481731389.4
    任务执行的时刻 1481731392.41 传达的消息是 world 任务建立时刻 1481731389.4
    睡眠2秒前时刻: 1481731392.41
    睡眠2秒结束时刻: 1481731394.41
    
    
    ----------  两个复杂的例子  -------------
    睡眠7秒前时刻: 1481731394.41
    睡眠7秒结束时刻: 1481731401.42
    睡眠6秒前时刻: 1481731401.42
    睡眠6秒结束时刻: 1481731407.42
    任务执行的时刻 1481731407.42 传达的消息是 hello world [3] 任务建立时刻 1481731394.41
    任务执行的时刻 1481731416.43 传达的消息是 hello world [15] 任务建立时刻 1481731401.42
    程序结束时刻 1481731416.43
    

    自调任务1

    任务快结束时利用 scheduler 又重新调用自己让自己“活过来”。

    # 计数器,一个循环任务,总共让自己执行3次
    total = 0 
    # 第二个工作函数,自调任务,自己开启定时并启动。
    def worker2(msg, starttime):
        global total
        total += 1
        print u'当前时刻:', time.time(), '消息是:', msg, ' 启动时间是:', starttime
        # 只要没有让自己调用到第3次,那么继续重头开始执行本任务
        if total < 3:
            # 这里的delay 可以重新指定
            s.enter(5, 2, worker2, ('perfect world %d' % (total), time.time()))
            s.run()
    
    print u'程序开始时刻:', time.time()
    # 开启自调任务
    s.enter(5, 2, worker2, ('perfect world %d' % (total), time.time()))
    s.run()
    print u'程序结束时刻:', time.time()
    
    程序开始时刻: 1481731439.42
    当前时刻: 1481731444.43 消息是: perfect world 0  启动时间是: 1481731439.42
    当前时刻: 1481731449.44 消息是: perfect world 1  启动时间是: 1481731444.43
    当前时刻: 1481731454.44 消息是: perfect world 2  启动时间是: 1481731449.44
    程序结束时刻: 1481731454.44
    

    Threading.Timer() 定时任务

    from threading import Timer
    import time
    
    def func(msg, starttime):
        print u'程序启动时刻:', starttime, '当前时刻:', time.time(), '消息内容 --> %s' % (msg)
        
    # 下面的两个语句和上面的 scheduler 效果一样的
    Timer(5, func, ('hello', time.time())).start()
    Timer(3, func, ('world', time.time())).start()
    
    程序启动时刻: 1481731467.28 当前时刻: 1481731470.28 消息内容 --> world
    程序启动时刻: 1481731467.28 当前时刻: 1481731472.28 消息内容 --> hello
    

    循环任务2

    利用 threading.Timer() 建立的自调任务

    count = 0
    def loopfunc(msg,starttime):
        global count
        print u'启动时刻:', starttime, ' 当前时刻:', time.time(), '消息 --> %s' % (msg)
        count += 1
        if count < 3:
            Timer(3, loopfunc, ('world %d' % (count), time.time())).start()
    
    Timer(3, loopfunc, ('world %d' % (count), time.time())).start()
    
    启动时刻: 1481731476.35  当前时刻: 1481731479.35 消息 --> world 0
    启动时刻: 1481731479.35  当前时刻: 1481731482.35 消息 --> world 1
    启动时刻: 1481731482.35  当前时刻: 1481731485.35 消息 --> world 2
  • 相关阅读:
    解决Hash冲突的几种方式
    深入理解JDK8中的HashMap
    JAVA中两个int类型的变量在不借助第三个变量的情况下完成值的互换
    Feign调用时读取超时(Read timed out executing GET)解决
    windows上Jenkins安装及其配置
    windows下查看端口被占用及处理
    flutter IOS模拟器无法弹出软键盘
    Android-ION内存管理简介
    移动GPU分类/百科
    ApiGen4.1 windows安装教程
  • 原文地址:https://www.cnblogs.com/LinTeX9527/p/6181523.html
Copyright © 2011-2022 走看看