python 定时任务

1、python定时任务之sched

sched 定时任务

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, …)是一个元组,里面存放的是函数的参数,若函数没有参数直接传入一个空元组()就可以了;
第三步:运行调度器。

例1:

# 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函数。

例2:

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.

例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 ?

使用多线程之后,就不会出现一个主线程运行的问题。

2、python定时任务之schedule

简单的schedule的定时任务如下:

例1:

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

例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

3、python定时任务之Timer

Timer的参数如下:

	Time(interval, function, args=None, k=None)

interval — 时间间隔
function — 参数名
args — 默认参数,默认为None
interval — 关键字参数
简单使用如下:

例1

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调用任务就可以了。

猜你喜欢

转载自blog.csdn.net/Darkman_EX/article/details/82886982