python任务调度框架_Python任务调度之sched

本文详细介绍了Python的sched模块,包括其基本用法、如何实现任务调度、取消任务及结合线程使用的方法。此外,还提供了一个使用sched模块周期性抓取网页内容并解析的实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这次我们主要讲解下Python自带模块当中的sched,不但小巧,也很强大,在实际应用中,某些场合还是可以用到的。作为一名Linux的SA,我们已经习惯了用crontab,而sched提供了一种延迟处理机制,也可以理解为任务调度的另一种方式的实现。

scheduler.enter(delay, priority, action, argument)

● delay:延迟时间

● priority:优先级(数越大,优先越低)

● action:回调函数

● argument:回调函数的参数

我们来写一个非常简单的例子:

#!/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)

运行结果如下:

START: 1453357480.74

Middle

action: make peace 1453357483.74

action: fight 1453357483.74

END: 1453357483.74

我们再举一个简单的例子说明下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)

运行结果如下:

START: 1339665268.12BEGIN: fight: 1339665270.12FINISH fight: 1339665272.12BEGIN: make peace: 1339665272.12FINISH make peace: 1339665274.12END: 1339665274.12

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

上面的例子第二个事件在第一个事件运行结束后立即运行,因为第一个事件的执行时间足够长,已经超过第二个事件的预期开始时刻。(本来应该1339660903秒运行)

我们再介绍另外一个保证action在同一时刻执行的函数:

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)

运行结果如下:

START: 1339666232.38

action: 1339666234.38 fight

action: 1339666234.38 make peace

END: 1339666232.38

因为优先级的关系,所以先fight,然后再make peace,打架是如此重要....总体来讲,如果想单纯的替换crontab的话,Scheduler框架更加适合,做延迟任务的调度处理的话sched还是可以考虑的。

如果我们想要取消任务调度,可以使用cancel()函数。在上面的例子中出现了阻塞延迟的现象,如果引用线程机制就会避免这种情况的发生,我们简单举个例子:

#!/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)

运行结果如下:

START: 1339666987.27

action: action2 1339666990.27

counter:  1

counter: 1

END: 1339666990.27

因为run()函数会引起阻塞,所以我们需要采用线程机制的方法在另一个线程中通过对象的引用取消任务调度,这里只调度了action2方法。

python使用sched模块周期性抓取网页内容

1.使用sched模块可以周期性地执行指定函数

2.在周期性执行指定函数中抓取指定网页,并解析出想要的网页内容,代码中是六维论坛的在线人数

论坛在线人数统计

#coding=utf-8

import time,sched,os,urllib2,re,string

#初始化sched模块的scheduler类

#第一个参数是一个可以返回时间戳的函数,第二个参数可以在定时未到达之前阻塞。

s = sched.scheduler(time.time,time.sleep)

#被周期性调度触发的函数

def event_func():

req = urllib2.Request('http://bt.neu6.edu.cn/')

response = urllib2.urlopen(req)

rawdata = response.read()

response.close()

usernump = re.compile(r'总计 .*? 人在线')

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

# 保存结果,供图表工具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四个参数分别为:间隔事件、优先级(用于同时间到达的两个事件同时执行时定序)、被调用触发的函数,给他的参数(注意:一定要以tuple给如,如果只有一个参数就(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()

本文出自别人博客,请务必保留此出处http://outofmemory.cn/code-snippet/3199/python-usage-sched-module-period-xing-zhuaqu-wangye-content

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值