Python_定时任务

没有使用apscheduler。自己实现了一个定时任务,目前可满足自己项目的需要。
采用跟linux类似的定时任务命令,不同的是这里不支持星期,增加了秒定时任务。
以下是源码。

class Cron:
    def __init__(self):
        self.log = logClass()
        self.now_tm = int(time.time())
        self.text_month = 'month'
        self.text_day = 'day'
        self.text_hour = 'hour'
        self.text_min = 'min'
        self.text_sec = 'sec'

    def getNowDetailTime(self):
        date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        # self.log.debug('now_date:{}'.format(int(date)))
        return date

    def getYear(self):
        date = datetime.datetime.now().strftime("%Y")
        # self.log.debug('now_year:{}'.format(int(date)))
        return int(date)

    def getMonth(self):
        date = datetime.datetime.now().strftime("%m")
        # self.log.debug('now_month:{}'.format(int(date)))
        return int(date)

    def getDay(self):
        date = datetime.datetime.now().strftime("%d")
        # self.log.debug('now_day:{}'.format(int(date)))
        return int(date)

    def getHour(self):
        date = datetime.datetime.now().strftime("%H")
        # self.log.debug('now_hour:{}'.format(int(date)))
        return int(date)

    def getMinute(self):
        date = datetime.datetime.now().strftime("%M")
        # self.log.debug('now_minute:{}'.format(int(date)))
        return int(date)

    def getSecond(self):
        date = datetime.datetime.now().strftime("%S")
        # self.log.debug('now_second:{}'.format(int(date)))
        return int(date)

    def getIntervalList(self,It,n,start):
        mlist = []
        if It==self.text_month or It==self.text_hour:
            for x in range(start, 13):
                if x % n == 0:
                    mlist.append(x)
        elif It==self.text_day:
            for x in range(start, GetCurrentMonthDay()+1):
                if x % n == 0:
                    mlist.append(x)
        elif It==self.text_min or It==self.text_sec:
            for x in range(start, 61):
                if x % n == 0:
                    mlist.append(x)

        # self.log.debug('type:[{}],n:[{}],mlist:{}'.format(It,n,mlist))
        return mlist



    def cron_controller(self,cron_str):
        """
        测试用例:
            *,*,*,*,*
            *,*,*,45,*
            *,*,*,45,0
            *,*,*,45,*/3
            *,*,*,*/1,*
            *,*,*,*/2,*
            *,*,*,*/4,*
            *,*,*/3,*/4,*
            *,*,*/3,*/4,0
            共计三种类型,有斜杠、全是* ,纯数字
        :param cron_str:
        :return:
        """
        r = {}
        rdict = {
            self.text_month:0,
            self.text_day:0,
            self.text_hour:0,
            self.text_min:0,
            self.text_sec:0,
            'is_pass':0,
            'cron_text':''
        }
        cron = str(cron_str).split('|') if '|' in str(cron_str) else 0
        if isinstance(cron,list):
            rdict['cron_text']=cron[1]
            cron = cron[0]
        else:
            cron = cron_str
        d = str(cron).split(',') if ',' in str(cron) else 0
        cron_dict = {}
        debug = {}

        if d != 0 and len(d) == 5:
            cron_dict['month']=d[0]
            cron_dict['day']=d[1]
            cron_dict['hour']=d[2]
            cron_dict['min']=d[3]
            cron_dict['sec']=d[4]
            r['cron']=cron_dict
            for stype,son in cron_dict.items():
                res = 0
                sb = 0
                sa = 0
                if '*' == son:
                    res=1
                elif '/' in son:
                    # 针对*/2 的情况
                    s = str(son).split('/')
                    if len(s)==2:
                        sb = int(s[0]) if '*' not in s[0] else 1
                        sa = int(s[1]) if '*' not in s[1] else 1
                        # self.log.debug('sb:{},sa:{}'.format(sb,sa))
                elif son.isdigit():
                    # 针对 指定时间执行的情况  *,*,*,45,*
                    res=2
                    sa=int(son)
                if res==0 and sb and sa: # sa=0的情况要单独处理,这个节点不允许进入执行
                    if stype==self.text_month:
                        self.now_month = self.getMonth()
                        if self.now_month%sb==0 and self.now_month %sa==0:
                            rdict[self.text_month]=1

                    if stype==self.text_day:
                        self.now_day = self.getDay()
                        if self.now_day % sb == 0 and self.now_day %sa==0:
                            rdict[self.text_day] = 1

                    if stype==self.text_hour:
                        self.now_hour = self.getHour()
                        if self.now_hour !=0:
                            if self.now_hour % sb == 0 and self.now_hour  %sa==0:
                                rdict[self.text_hour] = 1
                        else:
                            # 当小时等于=0 时,也就是24点,此时只要能被24 整除的定时任务配置都可以执行,故设置为通过,以此类推 时分秒 都有这种情况
                            if 24 %sa ==0:
                                rdict[self.text_hour] = 1
                    if stype==self.text_min:
                        self.now_min = self.getMinute()
                        if self.now_min==0:
                            # 当小时等于=0 时,*/1 */2 两种情况都有可能会在0点执行,故设置为通过,以此类推 时分秒 都有这种情况
                            if 60%sa==0:
                                rdict[self.text_min] = 1
                        else:
                            if self.now_min % sb == 0 and self.now_min %sa==0:
                                rdict[self.text_min] = 1

                    if stype==self.text_sec:
                        self.now_sec = self.getSecond()
                        if self.now_sec==0:
                            # 当小时等于=0 时,*/1 */2 两种情况都有可能会在0点执行,故设置为通过,以此类推 时分秒 都有这种情况
                            self.log.debug('sec:{},sa:{},res:{}'.format(self.now_sec,sa,60%sa))

                            if 60%sa==0:
                                rdict[self.text_sec] = 1
                        else:
                            if self.now_sec % sb == 0 and self.now_sec %sa == 0:
                                rdict[self.text_sec] = 1
                elif res==2: # 此时定时任务为整数,sa=0的情况针对时分秒要单独处理

                    if stype==self.text_month:
                        self.now_month = self.getMonth()
                        if sa !=0:
                            if self.now_month == sa:
                                rdict[self.text_month]=1

                    if stype==self.text_day:
                        if sa !=0:
                            self.now_day = self.getDay()
                            if self.now_day == sa:
                                rdict[self.text_day] = 1
                    if stype==self.text_hour:
                        self.now_hour = self.getHour()
                        if sa != 0:
                            if self.now_hour == sa:
                                rdict[self.text_hour] = 1
                        else:
                            if self.now_hour==0:
                                rdict[self.text_hour] = 1
                    if stype==self.text_min:
                        self.now_min = self.getMinute()
                        if sa != 0:
                            if self.now_min==sa:
                                rdict[self.text_min] = 1
                        else:
                            if self.now_min==0:
                                rdict[self.text_min] = 1
                    if stype==self.text_sec:
                        self.now_sec = self.getSecond()
                        if sa != 0:
                            if self.now_sec==sa:
                                rdict[self.text_sec] = 1
                        else:
                            if self.now_sec==0:
                                rdict[self.text_sec] = 1
                else:
                    debug['res_0']=1

                    if stype==self.text_month:
                        rdict[self.text_month]=1
                    if stype==self.text_day:
                        rdict[self.text_day]=1

                    if stype==self.text_hour:
                        rdict[self.text_hour]=1

                    if stype==self.text_min:
                        rdict[self.text_min]=1

                    if stype==self.text_sec:
                        rdict[self.text_sec]=1
                # self.log.debug('type:{},son:{},res:{},res_dict:{}'.format(stype, son, res,rdict))
            # self.log.debug('***** ok, rdict:{}'.format(rdict))
            if rdict[self.text_month] and rdict[self.text_day] and rdict[self.text_hour] and rdict[self.text_min] and rdict[self.text_sec]:
                rdict['is_pass'] = 1
        else:
            self.log.error('定时任务参数错误:{}'.format(cron))
        r['result']=rdict
        if rdict['is_pass']==1:
            self.log.debug(r)
        return r

    def debug(self):
        self.getNowDetailTime()
        self.getYear()
        self.getMonth()
        self.getDay()
        self.getHour()
        self.getMinute()
        self.getSecond()

cr = Cron()
# 将参数传递给装饰器,符合条件将后调用函数
def cron(cron_p):
    def func_wrapper(func):
        @wraps(func)
        def return_wrapper(*args, **wkargs):
            # 函数通过装饰起参数给装饰器传送参数
            res = cr.cron_controller(cron_p)
            if res['result']['is_pass']:
                func(*args, **wkargs)
        return return_wrapper
    return func_wrapper

使用方法:

import multiprocessing
@cron('*,*,*,*/5,0|auditUploadMonitor') # 竖线前面是定时任务,后面是说明
def auditUploadMonitor():
    aum= AuditUploadMonitor()
    aum.audit_overview()

def main():
    fun_list = [oneapstatistical, a,b,c,d]
    # fun_list=[authTotal,auditUploadMonitor]
    for i in fun_list:
        pool = multiprocessing.Process(target=i)    
        pool.start()
while True:
    time.sleep(1)
    main()

原理:

启动常驻主进程,然后每一秒轮训定时任务,如歌符合要求,则执行方法,否则不执行。

实现方法比较粗糙,欢迎多提意见。

猜你喜欢

转载自blog.csdn.net/weixin_34293902/article/details/88252927