主要是要实现tornado实现计划任务类crontab间隔
2015-09-18 14:06
711 查看
大家看了标题,可能知道我要写啥了 ~ 对头,我用tornado实现一个类似crontab时间间隔调度的程序。
我为啥要写这个?
一方面是 更加深入的了解tornado异步方面的能力 。 另一方面是 在特殊的环境下编写更适合更方便自己的工具。
啥特殊的环境?
比如,我们有好几个后端脚本,这些脚本都要间隔的运行调度。然而这些程序都是秒级别的,这样的话,你用crontab就不太适合了。当然你可以后台仍个脚本,然后sleep 也是可以的。 要是很多的话? 你运行多个脚本?
我上个监控校验项目——就有很多的后台有间隔的脚本跑着。每次系统有改变我都要kill掉进程,调试好了,再start,挺蛋疼的~
后来我把很多的监控校验都放到一个脚本里面,然后开多线程,让他自己去sleep。以后我只需要kill掉一个进程就行了。
Python本身自带了一个调度模块sched,timer,官方给出的例子,都是那样,调用一次的用法。
任务是并发执行的,但是s.run()会把线程堵塞掉,所以咱们有必要把s.run()放到一个独立的线程去运行。当然你要是有需要的话。
view sourceprint?
scheduler实例含有以下方法和属性:
view sourceprint?
需要关注的是 sched模块不是循环的,一次调度被执行后就完事了,如果想再执行,请再次enter事件了。
我们再来感受下sched里面的timer !
view sourceprint?
说完了后,我们这里跑个实际中能用到的例子:
我们跑看看,我们中间加了sleep 2s ,然而他所用的时间是7s,说明他是并发执行的。
关于线程的timer我简单写了个例子,跑了下,感觉怪怪的。
view sourceprint?
运行的结果,时不时的会乱,这东西不太适合做crontab的效果。
我这里微微的总结下:
按照我的测试,sched和timer不适合做循环的计划任务,当然你可以在sched调用函数的时候,用while sleep的方法实现也是靠谱的。。。。
感觉python应该有靠谱点的计划任务模块,问了下朋友,他们现在用的是 APScheduler
一个很牛逼的库~ 已经测试过了
特定时间的运行:
view sourceprint?
间隔的运行:
view sourceprint?
循环3s,ok !!!
哈,我简单说了下 python下实现计划任务的几种方式,本来要聊tornado,结果搞到标准库了。
晕,赶紧说正题:
python的web框架中tornado是强大的,他的IOLoop类是Tornado的边缘触发事件驱动模型,在Linux平台下面封装的是epoll模型。这就是他的异步模式的基础。
要是合成到tornado的ioloop的话,我启动一个主程序,不仅把相应的脚本按照间隔调度跑起来,主web也可以访问啦。
用python实现计划任务,除了python自带的shed,timer之外,我能想到的就是开多线程,自己去处理每个任务以及时间间隔。还有就是tornado的ioloop。
精力有限,现在还没有做出像linux系统下的crontab那样的工具。
我想到的思路是 配置文件可以就是crontab的时间语法,或者是咱们用yaml,configparser。程序启动的时候,开一个线程,专门关注这些个数据,对于任务和时间都要采用全局的变量,这些个函数进入主体的时候,先把global变量加载进来,然后大家就懂啦。。。。
下面是我用tornado ioloop实现的方法:
view sourceprint?
结果:
再跑计划任务的时候,不影响web的访问
一眨眼,发现自己原本要写tornado,结果成大杂烩了~
微微总结下这几种计划任务的方法:
sched 就原版的例子来说,不适合做循环执行的,就单个计划任务是挺不错的。要是想做循环,不要让那个线程死掉,一直while True: 就行了
timer 同sched,不知道为啥多任务的时候,出现奇怪的问题。。。
apscheduler 这个是利器,好用,也是必须推荐使用的。
tornado 我自己觉得是很不错的,他和别的方法不一样,别人是线程,他是异步回调的方式,他背靠着epoll异步,所以很爽。
自己写 这个实现的思路,其实和sched timer,差不多的,我也有提过,就是个多线程,然后while True
转自:http://www.it165.net/os/html/201310/6453.html
我为啥要写这个?
一方面是 更加深入的了解tornado异步方面的能力 。 另一方面是 在特殊的环境下编写更适合更方便自己的工具。
啥特殊的环境?
比如,我们有好几个后端脚本,这些脚本都要间隔的运行调度。然而这些程序都是秒级别的,这样的话,你用crontab就不太适合了。当然你可以后台仍个脚本,然后sleep 也是可以的。 要是很多的话? 你运行多个脚本?
我上个监控校验项目——就有很多的后台有间隔的脚本跑着。每次系统有改变我都要kill掉进程,调试好了,再start,挺蛋疼的~
后来我把很多的监控校验都放到一个脚本里面,然后开多线程,让他自己去sleep。以后我只需要kill掉一个进程就行了。
Python本身自带了一个调度模块sched,timer,官方给出的例子,都是那样,调用一次的用法。
任务是并发执行的,但是s.run()会把线程堵塞掉,所以咱们有必要把s.run()放到一个独立的线程去运行。当然你要是有需要的话。
view sourceprint?
01.
&
gt
;&
gt
;&
gt
;
import
sched,
time
02.
&
gt
;&
gt
;&
gt
; s = sched.scheduler(
time
.
time
,
time
.
sleep
)
03.
&
gt
;&
gt
;&
gt
; def print_time(): print
"From print_time"
,
time
.
time
()
04.
...
05.
&
gt
;&
gt
;&
gt
; def print_some_times():
06.
time
.
time
()
07.
... s.enter(5, 1, print_time, ())
08.
... s.enter(10, 1, print_time, ())
09.
... s.run()
10.
time
.
time
()
11.
...
12.
&
gt
;&
gt
;&
gt
; print_some_times()
13.
930343690.257
14.
From print_time 930343695.274
15.
From print_time 930343700.273
16.
930343700.276
scheduler实例含有以下方法和属性:
view sourceprint?
01.
scheduler.enterabs(
time
, priority, action, argument)
02.
调度一个新事件,
time
参数应该是数值类型的。
03.
scheduler.enter(delay, priority, action, argument)
04.
延迟调度一个事件,不同于相对时间
05.
scheduler.cancel(event)
06.
在事件队列中移除一个事件,如果事件不在事件队列中,则触发ValueError
07.
scheduler.empty()
08.
如果事件队列为空则返回True
09.
scheduler.run()
10.
运行所有的调度事件,该函数会等待下一个事件,然后执行他直到没有可调度的事件为止。
11.
scheduler.queue
12.
只读属性,返回一个list,里面包含了即将运行的事件列表。
需要关注的是 sched模块不是循环的,一次调度被执行后就完事了,如果想再执行,请再次enter事件了。
我们再来感受下sched里面的timer !
view sourceprint?
01.
&
gt
;&
gt
;&
gt
;
import
time
02.
&
gt
;&
gt
;&
gt
; from threading
import
Timer
03.
&
gt
;&
gt
;&
gt
; def print_time():
04.
"From print_time"
,
time
.
time
()
05.
...
06.
&
gt
;&
gt
;&
gt
; def print_some_times():
07.
time
.
time
()
08.
... Timer(5, print_time, ()).start()
09.
... Timer(10, print_time, ()).start()
10.
...
time
.
sleep
(11)
# sleep while time-delay events execute
11.
time
.
time
()
12.
...
13.
&
gt
;&
gt
;&
gt
; print_some_times()
14.
930343690.257
15.
From print_time 930343695.274
16.
From print_time 930343700.273
17.
930343701.301
说完了后,我们这里跑个实际中能用到的例子:
我们跑看看,我们中间加了sleep 2s ,然而他所用的时间是7s,说明他是并发执行的。
关于线程的timer我简单写了个例子,跑了下,感觉怪怪的。
view sourceprint?
01.
import
threading
02.
import
time
03.
def timer_start():
04.
t = threading.Timer(2,func,(
"xiaorui.cc"
,
"2s"
))
05.
t.start()
06.
t2 = threading.Timer(4,rui,(
"4s"
,
"nima"
))
07.
t2.start()
08.
def func(msg1,msg2):
09.
"come on,"
,msg1,msg2
10.
time
.strftime('%Y%m%d%H%M %S')
11.
timer_start()
12.
def rui(msg3,nima):
13.
print 'this is rui %s %s'%(msg3,nima)
14.
timer_start()
15.
if
__name__ ==
"__main__"
:
16.
timer_start()
17.
while
True:
18.
time
.
sleep
(1)
运行的结果,时不时的会乱,这东西不太适合做crontab的效果。
我这里微微的总结下:
按照我的测试,sched和timer不适合做循环的计划任务,当然你可以在sched调用函数的时候,用while sleep的方法实现也是靠谱的。。。。
感觉python应该有靠谱点的计划任务模块,问了下朋友,他们现在用的是 APScheduler
一个很牛逼的库~ 已经测试过了
特定时间的运行:
view sourceprint?
1.
from apscheduler.scheduler
import
Scheduler
2.
sched = Scheduler()
3.
sched.daemonic = False
4.
def job_function(text):
5.
print text
6.
from datetime
import
datetime
7.
job = sched.add_date_job(job_function, datetime(2013, 10, 11, 02, 36, 00), ['Hello World'])
8.
sched.start()
间隔的运行:
view sourceprint?
01.
from apscheduler.scheduler
import
Scheduler
02.
import
time
03.
sched = Scheduler()
04.
sched.daemonic = False
05.
def job_function():
06.
"wan si ni"
07.
time
.strftime('%Y%m%d%H%M %S')
08.
sched.add_interval_job(job_function, seconds=3)
09.
sched.start()
循环3s,ok !!!
哈,我简单说了下 python下实现计划任务的几种方式,本来要聊tornado,结果搞到标准库了。
晕,赶紧说正题:
python的web框架中tornado是强大的,他的IOLoop类是Tornado的边缘触发事件驱动模型,在Linux平台下面封装的是epoll模型。这就是他的异步模式的基础。
要是合成到tornado的ioloop的话,我启动一个主程序,不仅把相应的脚本按照间隔调度跑起来,主web也可以访问啦。
用python实现计划任务,除了python自带的shed,timer之外,我能想到的就是开多线程,自己去处理每个任务以及时间间隔。还有就是tornado的ioloop。
精力有限,现在还没有做出像linux系统下的crontab那样的工具。
我想到的思路是 配置文件可以就是crontab的时间语法,或者是咱们用yaml,configparser。程序启动的时候,开一个线程,专门关注这些个数据,对于任务和时间都要采用全局的变量,这些个函数进入主体的时候,先把global变量加载进来,然后大家就懂啦。。。。
下面是我用tornado ioloop实现的方法:
view sourceprint?
01.
from tornado
import
web, ioloop
02.
import
datetime
03.
period = 5 * 1000
# every 5 s
04.
class MainHandler(web.RequestHandler):
05.
def get(self):
06.
self.write('Hello Tornado')
07.
def like_cron():
08.
print datetime.datetime.now()
09.
def xiaorui():
10.
print 'xiaorui 2s'
11.
def lee():
12.
print 'lee 3s'
13.
14.
if
__name__ == '__main__':
15.
application = web.Application([
16.
(r'/', MainHandler),
17.
])
18.
application.listen(8081)
19.
ioloop.PeriodicCallback(like_cron, period).start()
# start scheduler
20.
ioloop.PeriodicCallback(lee, 3000).start()
# start scheduler
21.
ioloop.IOLoop.instance().start()
结果:
再跑计划任务的时候,不影响web的访问
一眨眼,发现自己原本要写tornado,结果成大杂烩了~
微微总结下这几种计划任务的方法:
sched 就原版的例子来说,不适合做循环执行的,就单个计划任务是挺不错的。要是想做循环,不要让那个线程死掉,一直while True: 就行了
timer 同sched,不知道为啥多任务的时候,出现奇怪的问题。。。
apscheduler 这个是利器,好用,也是必须推荐使用的。
tornado 我自己觉得是很不错的,他和别的方法不一样,别人是线程,他是异步回调的方式,他背靠着epoll异步,所以很爽。
自己写 这个实现的思路,其实和sched timer,差不多的,我也有提过,就是个多线程,然后while True
转自:http://www.it165.net/os/html/201310/6453.html
相关文章推荐
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- install and upgrade scrapy
- Scrapy的架构介绍
- Centos6 编译安装Python
- 使用Python生成Excel格式的图片
- 让Python文件也可以当bat文件运行
- [Python]推算数独
- Python中zip()函数用法举例
- Python中map()函数浅析
- Python将excel导入到mysql中
- Python在CAM软件Genesis2000中的应用
- 使用Shiboken为C++和Qt库创建Python绑定
- FREEBASIC 编译可被python调用的dll函数示例
- Python 七步捉虫法