Python 定时任务

来源:互联网 发布:kailas知乎 编辑:程序博客网 时间:2024/05/09 12:53

1. sched

https://docs.python.org/2/library/sched.html

作为一名Linux的SA,我们已经习惯了用crontab,而sched提供了一种延迟处理机制,也可以理解为任务调度的另一种方式的实现。

注意:

sched模块不是循环的,一次调度被执行后就Over了,如果想再执行,请再次enter

run()一直被阻塞,直到所有事件被全部执行完. 每个事件在同一线程中运行,所以如果一个事件的执行时间大于其他事件的延迟时间,那么,就会产生重叠。重叠的解决方法是推迟后来事件的执行时间。这样保证没有丢失任何事件,但这些事件的调用时刻会比原先设定的迟。

从3.3版本开始,scheduler是线程安全的。

举例:

import sched, times = sched.scheduler(time.time, time.sleep)def do_something(sc):    print "Doing stuff..."    # do you stuff    sc.enter(2, 1, do_something, (sc,))s.enter(2, 1, do_something, (s,))s.run()

2. threading.Timer

https://docs.python.org/2/library/threading.html?highlight=timer#timer-objects

Timer 不是循环的,一次调度被执行后就Over了,如果想再执行,请再次enter

举例:

#!/usr/bin/env pythonfrom threading import Timerfrom time import sleepclass RepeatedTimer(object):    def __init__(self, interval, function, *args, **kwargs):        self._timer = None        self.interval = interval        self.function = function        self.args = args        self.kwargs = kwargs        self.is_running = False        self.start()    def _run(self):        self.is_running = False        self.start()        self.function(*self.args, **self.kwargs)    def start(self):        if not self.is_running:            self._timer = Timer(self.interval, self._run)            self._timer.start()            self.is_running = True    def stop(self):        self._timer.cancel()        self.is_running = Falsedef hello(name):    print "Hello %s!" % nameprint "starting..."rt = RepeatedTimer(1, hello, "World")try:    sleep(5)finally:    rt.stop()

3. APScheduler

https://apscheduler.readthedocs.org/en/latest/

APScheduler 是一个 Python 定时任务框架,使用起来十分方便。提供了基于日期、固定时间间隔以及 crontab 类型的任务,并且可以持久化任务、并以 daemon 方式运行应用

举例:

from apscheduler.schedulers.blocking import BlockingSchedulerfrom datetime import datetimeimport timeimport osdef tick():    print('Tick! The time is: %s' % datetime.now())scheduler = BlockingScheduler()scheduler.add_job(tick, 'interval', seconds=2)print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C'))try:    scheduler.start()except (KeyboardInterrupt, SystemExit):    scheduler.shutdown() 

后台执行任务:

from datetime import datetimeimport timeimport osfrom apscheduler.schedulers.background import BackgroundSchedulerdef tick():    print('Tick! The time is: %s' % datetime.now())if __name__ == '__main__':    scheduler = BackgroundScheduler()    scheduler.add_job(tick, 'interval', seconds=2)    scheduler.start()    print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C'))    try:        # This is here to simulate application activity (which keeps the main thread alive).        while True:            time.sleep(5)    except (KeyboardInterrupt, SystemExit):        # Not strictly necessary if daemonic mode is enabled but should be done if possible        scheduler.shutdown()

4. gevent

Gevent 是一种基于协程的 Python 网络库,它用到 Greenlet 提供的,封装了 libevent 事件循环的高层同步 API。

Gevent 是一个基于 greenlet 的 Python 的并发框架,以微线程 greenlet 为核心,使用了 epoll 事件监听机制以及诸多其他优化而变得高效。

于 greenlet、eventlet 相比,性能略低,但是它封装的 API 非常完善,最赞的是提供了一个 monkey 类,可以将现有基于 Python 线程直接转化为 greenlet,相当于 proxy 了一下(打了 patch)。

举例:

import geventimport gevent.monkeygevent.monkey.patch_all()# 方法一:gevent.spawn_later 创建定时器def schedule(delay, func, *args, **kw_args):    gevent.spawn_later(0, func, *args, **kw_args)    gevent.spawn_later(delay, schedule, delay, func, *args, **kw_args)# 方法二:死循环中 gevent.sleepdef run_reqularly(self, function, interval, *args, **kwargs):    while True:        gevent.sleep(interval)        function(*args, **kwargs)# 方法三:同方法二,间隔时间更准确def run_reqularly2(self, function, interval, *args, **kwargs):    while True:        before = time.time()        function(*args, **kwargs)        duration = time.time() - before        if duration < interval:            gevent.sleep(interval-duration)        else:            warning("function %s duration exceeded %f interval (took %f)"             % (function.__name__, interval, duration))def test1():    print "func test1"def test2():    print "func test2"def test3():    print "func test3"schedule(1,test1)schedule(2,test2)schedule(3,test3)while True:    gevent.sleep(10)

5. Twisted

Twisted 是用 Python 实现的基于事件驱动的网络引擎框架。

举例:

from twisted.internet import taskfrom twisted.internet import reactordef runEverySecond():    print "a second has passed"l = task.LoopingCall(runEverySecond)l.start(1.0) # call every second# l.stop() will stop the looping callsreactor.run()

6. Celery

http://celery.readthedocs.io/en/latst/userguide/periodic-tasks.html

举例:

from datetime import timedeltafrom celery import Celeryapp = Celery('app1')app.conf.update(    CELERYBEAT_SCHEDULE = {        'mytimer': {            'task': 'myfunc',            'schedule': timedelta(seconds=2),        },    },    CELERY_TIMEZONE = 'UTC',)@app.task(name='myfunc')def runEverySecond():    print "a second has passed"

7. Tornado

由 Facebook 开源出来的 web 服务器框架。Tornado 采用多进程 + 非阻塞 + epoll 的模型,可以提供比较强大的网络响应性能

IOLoop 基于 epoll,可以高效的响应网络事件

举例:

from tornado import web, ioloopimport datetimeclass MainHandler(web.RequestHandler):    def get(self):        self.write('Hello Tornado')def f2s():    print '2s ', datetime.datetime.now()def f5s():    print '5s ', datetime.datetime.now()if __name__ == '__main__':    application = web.Application([        (r'/', MainHandler),        ])    application.listen(8081)    ioloop.PeriodicCallback(f2s, 2000).start()  # start scheduler    ioloop.PeriodicCallback(f5s, 5000).start()  # start scheduler    ioloop.IOLoop.instance().start()

参考

  • What is the best way to repeatedly execute a function every x seconds in Python?
  • Python的sched模块和Timer类
  • Python任务调度之sched
  • Python任务调度模块 – APScheduler
  • APScheduler —— Python化的Cron
  • apscheduler.schedulers.background
  • 使用gevent spawn_later实现定时计划任务系统
  • something like cron (timer) in gevent
  • Tornado/Twisted - Celery - Gevent Comparison
  • Scheduling tasks for the future
  • “Twisted与异步编程入门”系列文章的简体中文翻译
  • tornado实现异步计划任务及python常见计划任务方法
  • Using Celery to schedule python tasks
  • Celery documentation - Periodic Tasks

-eof-

0 0
原创粉丝点击