python任务调度框架_Python任务调度之sched
這次我們主要講解下Python自帶模塊當(dāng)中的sched,不但小巧,也很強(qiáng)大,在實(shí)際應(yīng)用中,某些場(chǎng)合還是可以用到的。作為一名Linux的SA,我們已經(jīng)習(xí)慣了用crontab,而sched提供了一種延遲處理機(jī)制,也可以理解為任務(wù)調(diào)度的另一種方式的實(shí)現(xiàn)。
scheduler.enter(delay, priority, action, argument)
● delay:延遲時(shí)間
●?priority:優(yōu)先級(jí)(數(shù)越大,優(yōu)先越低)
●?action:回調(diào)函數(shù)
●?argument:回調(diào)函數(shù)的參數(shù)
我們來(lái)寫(xiě)一個(gè)非常簡(jiǎn)單的例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sched
import time
scheduler = sched.scheduler(time.time, time.sleep)
def func(name):
print 'action: %s' % name , time.time()
print 'START:', time.time()
scheduler.enter(3, 2, func, ('fight',))
print 'Middle'
scheduler.enter(3, 1, func, ('make peace',))
scheduler.run()
print 'END:', time.time()
time.sleep(5)
運(yùn)行結(jié)果如下:
START: 1453357480.74
Middle
action: make peace 1453357483.74
action: fight 1453357483.74
END: 1453357483.74
我們?cè)倥e一個(gè)簡(jiǎn)單的例子說(shuō)明下sched的其它特性:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sched
import time
scheduler = sched.scheduler(time.time, time.sleep)
def func(name):
print 'BEGIN: %s:' % name, time.time()
time.sleep(2)
print 'FINISH %s:' % name, time.time()
print 'START:', time.time()
scheduler.enter(2, 1, func, ('fight',))
scheduler.enter(3, 1, func, ('make peace',))
scheduler.run()
print 'END:', time.time()
time.sleep(20)
運(yùn)行結(jié)果如下:
START: 1339665268.12BEGIN: fight: 1339665270.12FINISH fight: 1339665272.12BEGIN: make peace: 1339665272.12FINISH make peace: 1339665274.12END: 1339665274.12
我們仔細(xì)觀察下兩次任務(wù)調(diào)度的時(shí)間間隔,發(fā)現(xiàn)是同時(shí)運(yùn)行的?那又是為什么呢?run()一直被阻塞,直到所有事件被全部執(zhí)行完. 每個(gè)事件在同一線程中運(yùn)行,所以如果一個(gè)事件的執(zhí)行時(shí)間大于其他事件的延遲時(shí)間,那么,就會(huì)產(chǎn)生重疊。重疊的解決方法是推遲后來(lái)事件的執(zhí)行時(shí)間。這樣保證 沒(méi)有丟失任何事件,但這些事件的調(diào)用時(shí)刻會(huì)比原先設(shè)定的遲。
上面的例子第二個(gè)事件在第一個(gè)事件運(yùn)行結(jié)束后立即運(yùn)行,因?yàn)榈谝粋€(gè)事件的執(zhí)行時(shí)間足夠長(zhǎng),已經(jīng)超過(guò)第二個(gè)事件的預(yù)期開(kāi)始時(shí)刻。(本來(lái)應(yīng)該1339660903秒運(yùn)行)
我們?cè)俳榻B另外一個(gè)保證action在同一時(shí)刻執(zhí)行的函數(shù):
scheduler.enterabs(time, priority, action, argument)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sched
import time
scheduler = sched.scheduler(time.time, time.sleep)
now = time.time()
def func(name):
print 'action:', time.time(), name
print 'START:', now
scheduler.enterabs(now + 2, 2, func, ('make peace',))
scheduler.enterabs(now + 2, 1, func, ('fight',))
scheduler.run()
print 'END:', now
time.sleep(20)
運(yùn)行結(jié)果如下:
START: 1339666232.38
action: 1339666234.38?fight
action: 1339666234.38?make peace
END: 1339666232.38
因?yàn)閮?yōu)先級(jí)的關(guān)系,所以先f(wàn)ight,然后再make peace,打架是如此重要....總體來(lái)講,如果想單純的替換crontab的話,Scheduler框架更加適合,做延遲任務(wù)的調(diào)度處理的話sched還是可以考慮的。
如果我們想要取消任務(wù)調(diào)度,可以使用cancel()函數(shù)。在上面的例子中出現(xiàn)了阻塞延遲的現(xiàn)象,如果引用線程機(jī)制就會(huì)避免這種情況的發(fā)生,我們簡(jiǎn)單舉個(gè)例子:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sched
import threading
import time
scheduler = sched.scheduler(time.time, time.sleep)
counter = 0
def increment_counter(name):
global counter
print 'action: %s' % name , time.time()
counter += 1
print 'counter: ', counter
print 'START:', time.time()
action1 = scheduler.enter(2, 1, increment_counter, ('action1',))
action2 = scheduler.enter(3, 1, increment_counter, ('action2',))
t = threading.Thread(target=scheduler.run)
t.start()
scheduler.cancel(action1)
t.join()
print 'counter:', counter
print 'END:', time.time()
time.sleep(20)
運(yùn)行結(jié)果如下:
START: 1339666987.27
action:?action2?1339666990.27
counter:??1
counter: 1
END: 1339666990.27
因?yàn)閞un()函數(shù)會(huì)引起阻塞,所以我們需要采用線程機(jī)制的方法在另一個(gè)線程中通過(guò)對(duì)象的引用取消任務(wù)調(diào)度,這里只調(diào)度了action2方法。
python使用sched模塊周期性抓取網(wǎng)頁(yè)內(nèi)容
1.使用sched模塊可以周期性地執(zhí)行指定函數(shù)
2.在周期性執(zhí)行指定函數(shù)中抓取指定網(wǎng)頁(yè),并解析出想要的網(wǎng)頁(yè)內(nèi)容,代碼中是六維論壇的在線人數(shù)
論壇在線人數(shù)統(tǒng)計(jì)
#coding=utf-8
import time,sched,os,urllib2,re,string
#初始化sched模塊的scheduler類(lèi)
#第一個(gè)參數(shù)是一個(gè)可以返回時(shí)間戳的函數(shù),第二個(gè)參數(shù)可以在定時(shí)未到達(dá)之前阻塞。
s = sched.scheduler(time.time,time.sleep)
#被周期性調(diào)度觸發(fā)的函數(shù)
def event_func():
req = urllib2.Request('http://bt.neu6.edu.cn/')
response = urllib2.urlopen(req)
rawdata = response.read()
response.close()
usernump = re.compile(r'總計(jì) .*? 人在線')
usernummatch = usernump.findall(rawdata)
if usernummatch:
currentnum=usernummatch[0]
currentnum=currentnum[string.index(currentnum,'>')+1:string.rindex(currentnum,'
print "Current Time:",time.strftime('%Y,%m,%d,%H,%M',time.localtime(time.time())),'User num:',currentnum
# 保存結(jié)果,供圖表工具amcharts使用
result=open('liuvUserNUm','a')
result.write('{year: new Date('+time.strftime('%Y,%m,%d,%H,%M',time.localtime(time.time()))+'),value:'+currentnum+'},\n')
result.close()
#enter四個(gè)參數(shù)分別為:間隔事件、優(yōu)先級(jí)(用于同時(shí)間到達(dá)的兩個(gè)事件同時(shí)執(zhí)行時(shí)定序)、被調(diào)用觸發(fā)的函數(shù),給他的參數(shù)(注意:一定要以tuple給如,如果只有一個(gè)參數(shù)就(xx,))
def perform(inc):
s.enter(inc,0,perform,(inc,))
event_func()
def mymain(inc=900):
s.enter(0,0,perform,(inc,))
s.run()
if __name__ == "__main__":
mymain()
本文出自別人博客,請(qǐng)務(wù)必保留此出處http://outofmemory.cn/code-snippet/3199/python-usage-sched-module-period-xing-zhuaqu-wangye-content
總結(jié)
以上是生活随笔為你收集整理的python任务调度框架_Python任务调度之sched的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: deepin安装java_Deepin
- 下一篇: 解非线性方程的两种方法与python实现