sched的使用步骤如下:
s = sched.scheduler(time.time, time.sleep)
s.enter(delay, priority, func1, (arg1, arg2, ...))
s.run()
第一步:新建一个调度器,time.time表示可以返回时间戳, time.sleep表示定时任务阻塞;
第二步:添加调度任务,可以添加多个任务,delay表示间隔事件,相对于调度器添加这个任务时刻的延时,以秒为单位,priority表示优先级(数字越小优先级越高),func指的是调用的函数名,(arg1, arg2, …)是一个元组,里面存放的是函数的参数,若函数没有参数直接传入一个空元组()就可以了;
第三步:运行调度器。
# coding:utf8
import os
import time
import sched
import threading
import datetime
def task():
now = str(datetime.datetime.now()).split('.')[0]
print('当前时间:%s, 进程pid:%s , 线程pid:%s ' % (now, os.getpid(), threading.current_thread().name))
# os.getpid()获取当前进程id os.getppid()获取父进程id
if __name__ == '__main__':
now = str(datetime.datetime.now()).split('.')[0]
print(now)
s = sched.scheduler(time.time, time.sleep)
s.enter(10, 0, task, ()) # 10秒之后执行函数,该函数没有参数所以传入一个空元组,若有参数,把参数传入元组,并用逗号隔开比如(arg1, arg2, ...)
s.run()
# 2018-09-28 10:33:25
# 当前时间:2018-09-28 10:33:35, 进程pid:11228 , 线程pid:MainThread
例一中,休眠10秒之后执行task函数。
import os
import time
import sched
import threading
import datetime
def task(msg):
time.sleep(1)
now = str(datetime.datetime.now()).split('.')[0]
print('当前时间:%s, 进程pid:%s , 线程pid:%s , message:%s' % (now, os.getpid(), threading.current_thread().name, msg))
# os.getpid()获取当前进程id os.getppid()获取父进程id
if __name__ == '__main__':
now = str(datetime.datetime.now()).split('.')[0]
print(now)
s = sched.scheduler(time.time, time.sleep)
s.enter(5, 0, task, ('Hello, world !',))
s.enter(5, 0, task, ('Hi, my friend !',))
s.enter(5, 0, task, ('Are you ok ?',))
s.run()
# 2018-09-28 11:10:05
# 当前时间:2018-09-28 11:10:11, 进程pid:8892 , 线程pid:MainThread , message:Hello, world !
# 当前时间:2018-09-28 11:10:12, 进程pid:8892 , 线程pid:MainThread , message:Hi, my friend !
# 当前时间:2018-09-28 11:10:13, 进程pid:8892 , 线程pid:MainThread , message:Are you ok ?
总结:sched调度函数可以定时执行,但是3个函数并没有在同一时间点运行,即便把函数的优先级设置为一样的,程序会根据添加任务的先后顺序执行,只有主线程再跑,若想用多线程跑,见例3.
import os
import time
import sched
import threading
import datetime
def work(msg):
now = str(datetime.datetime.now())
print('当前时间:%s, 进程pid:%s , 线程pid:%s , message:%s' % (now, os.getpid(), threading.current_thread().name, msg))
# os.getpid()获取当前进程id os.getppid()获取父进程id
def task1():
threading.Thread(target=work, args=('Hello, world !',)).start()
def task2():
threading.Thread(target=work, args=('Hi, my friend !',)).start()
def task3():
threading.Thread(target=work, args=('Are you ok ?',)).start()
if __name__ == '__main__':
for _ in range(5):
now = str(datetime.datetime.now()).split('.')[0]
print(now)
s = sched.scheduler(time.time, time.sleep)
s.enter(5, 0, task1, ())
s.enter(5, 0, task2, ())
s.enter(5, 0, task3, ())
s.run()
# 2018-09-28 11:06:51
# 当前时间:2018-09-28 11:06:56.302816, 进程pid:1908 , 线程pid:Thread-1 , message:Hello, world !
# 当前时间:2018-09-28 11:06:56.303275, 进程pid:1908 , 线程pid:Thread-2 , message:Hi, my friend !
# 当前时间:2018-09-28 11:06:56.303771, 进程pid:1908 , 线程pid:Thread-3 , message:Are you ok ?
使用多线程之后,就不会出现一个主线程运行的问题。
简单的schedule的定时任务如下:
import datetime
import schedule
import threading
def task():
now = str(datetime.datetime.now()).split('.')[0]
print('当前时间:%s, 进程Pid: %s, 线程pid:%s' % (now, os.getppid(), threading.current_thread().name))
if __name__ == '__main__':
counter = 0
schedule.every(0.1).minutes.do(task) # 每0.1分钟运行一次,也就是6秒执行一次
while True:
schedule.run_pending()
# 当前时间:2018-09-28 16:23:48, 进程Pid: 11320, 线程pid:MainThread
# 当前时间:2018-09-28 16:23:54, 进程Pid: 11320, 线程pid:MainThread
# 当前时间:2018-09-28 16:24:00, 进程Pid: 11320, 线程pid:MainThread
# 当前时间:2018-09-28 16:24:06, 进程Pid: 11320, 线程pid:MainThread
# 当前时间:2018-09-28 16:24:12, 进程Pid: 11320, 线程pid:MainThread
# schedule.every(5).minutes.do(task) 每5分钟运行
# schedule.every(1).hour.do(task) 每1小时运行
# schedule.every().day.at("9:00").do(task) 每天9:00的时候运行
# schedule.every(5).to(10).days.do(task)
# schedule.every().monday.do(task)
# schedule.every().wednesday.at("13:15").do(task)
schedule多线程定时任务与sched大同小异见例2
import os
import time
import schedule
import threading
import datetime
def work(msg):
now = str(datetime.datetime.now())
print('当前时间:%s, 进程pid:%s , 线程pid:%s , message:%s' % (now, os.getpid(), threading.current_thread().name, msg))
# os.getpid()获取当前进程id, os.getppid()获取父进程id
def task():
for i in range(3):
threading.Thread(target=work, args=(str(i),)).start()
if __name__ == '__main__':
now = str(datetime.datetime.now()).split('.')[0]
print(now)
schedule.every(5).seconds.do(task)
while True:
schedule.run_pending()
# 2018-09-28 16:43:44
# 当前时间:2018-09-28 16:43:49.331639, 进程pid:11316 , 线程pid:Thread-1 , message:0
# 当前时间:2018-09-28 16:43:49.331639, 进程pid:11316 , 线程pid:Thread-2 , message:1
# 当前时间:2018-09-28 16:43:49.332136, 进程pid:11316 , 线程pid:Thread-3 , message:2
Timer的参数如下:
Time(interval, function, args=None, k=None)
interval — 时间间隔
function — 参数名
args — 默认参数,默认为None
interval — 关键字参数
简单使用如下:
import time
import datetime
import threading
from threading import Timer
def task(msg):
time.sleep(7)
now = str(datetime.datetime.now()).split('.')[0]
print('当前时间:%s, Pid: %s, message:%s, Threading: %s' % (now, os.getpid(), msg, threading.current_thread().name))
if __name__ == '__main__':
now = str(datetime.datetime.now()).split('.')[0]
print(now)
Timer(10, task, ('WORLD1',)).start()
# 2018-09-28 16:48:05
# 当前时间:2018-09-28 16:48:22, Pid: 8572, message:WORLD1, Threading: Thread-1
threading中的Timer定时任务与sched、schedule显然不同,它本身已经封装好了多线程,在上例中可见,定时任务的函数是用子线程运行的,要用多线程那么多使用Timer调用任务就可以了。