schedule_scheduled - CSDN
精华内容
参与话题
  • 定时任务(Schedule的使用)

    千次阅读 2019-12-24 09:47:41
    1.new Timer().schedule(new TimerTask(), 2000);//定时任务只执行一次,如何循环调用呢? 可以在new TimerTask的run方法中再new 新的Timer(),也可以调用自己,也可以调用另外的定时器,形成循环即可实现每隔几秒执行一...

    1.new Timer().schedule(new TimerTask(), 2000);//定时任务只执行一次,如何循环调用呢?

    可以在new TimerTask的run方法中再new 新的Timer(),也可以调用自己,也可以调用另外的定时器,形成循环即可实现每隔几秒执行一次

    简单的定时任务可以直接用这种放法,如果比较复杂可以用插件quazt

    2.schedule

    springboot中@schedule注解实现定时任务:

    在启动类添加注解

    加入spring控制

    scheduled注解默认是单线程运行的,也就是多个定时任务如果设置同时或者一个还没跑完另一个时间到了的话,也只能等上一个定时任务运行完才能运行,

    如果要想异步执行,据说是只要加上@Asycn即可,但是实际测试不行,不知道是不是还要其他配置,

    另一种方法就是自定义配置类去重写Scheduled线程池初始化方法:

     

    展开全文
  • schedule()函数详解

    千次阅读 2019-02-20 16:58:20
    asmlinkage __visible void __sched schedule(void) { struct task_struct *tsk = current; sched_submit_work(tsk); do { __schedule(); } while (need_resched()); } schedul...
     asmlinkage __visible void __sched schedule(void)
     {
         struct task_struct *tsk = current;
     
         sched_submit_work(tsk);
         do {
             __schedule();
         } while (need_resched());
     }
    
    

    schedule主要完成的工作内容如下:
    (1)sched_submit_work用于检测当前进程是否有plugged io需要处理,由于当前进程执行schedule后,有可能会进入休眠,所以在休眠之前需要把plugged io处理掉放置死锁。
    (2)执行__schedule()这个函数是调度的核心处理函数,当前CPU会选择到下一个合适的进程去执行了。
    (3)need_resched()执行到这里时说明当前进程已经被调度器再次执行了,此时要判断是否需要再次执行调度。

     static void __sched __schedule(void)
     {
         struct task_struct *prev, *next;
         unsigned long *switch_count;
         struct rq *rq;
         int cpu;
     
         preempt_disable();
         cpu = smp_processor_id();
         rq = cpu_rq(cpu);
         rcu_note_context_switch();
         prev = rq->curr;
     
         schedule_debug(prev);
     
         if (sched_feat(HRTICK))
             hrtick_clear(rq);
     
         /*
          * Make sure that signal_pending_state()->signal_pending() below
          * can't be reordered with __set_current_state(TASK_INTERRUPTIBLE)
          * done by the caller to avoid the race with signal_wake_up().
          */
         smp_mb__before_spinlock();
         raw_spin_lock_irq(&rq->lock);
     
         rq->clock_skip_update <<= 1; /* promote REQ to ACT */
     
         switch_count = &prev->nivcsw;
         if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
             if (unlikely(signal_pending_state(prev->state, prev))) {
                 prev->state = TASK_RUNNING;
             } else {
                 deactivate_task(rq, prev, DEQUEUE_SLEEP);
                 prev->on_rq = 0;
     
                 /*
                  * If a worker went to sleep, notify and ask workqueue
                  * whether it wants to wake up a task to maintain
                  * concurrency.
                  */
                 if (prev->flags & PF_WQ_WORKER) {
                     struct task_struct *to_wakeup;
     
                     to_wakeup = wq_worker_sleeping(prev, cpu);
                     if (to_wakeup)
                         try_to_wake_up_local(to_wakeup);
                 }
             }
             switch_count = &prev->nvcsw;
         }
     
         if (task_on_rq_queued(prev))
             update_rq_clock(rq);
     
         next = pick_next_task(rq, prev);
         clear_tsk_need_resched(prev);
         clear_preempt_need_resched();
         rq->clock_skip_update = 0;
     
         if (likely(prev != next)) {
             rq->nr_switches++;
             rq->curr = next;
             ++*switch_count;
     
             rq = context_switch(rq, prev, next); /* unlocks the rq */
             cpu = cpu_of(rq);
         } else
             raw_spin_unlock_irq(&rq->lock);
     
         post_schedule(rq);
     
         sched_preempt_enable_no_resched();
     }
    
    

    (1)内核中定义了一个每CPU变量(percpu)runqueue,这个runqueue中是用来管理当前CPU上的running状态的进程,本函数会先获取当前CPU上的runqueue,然后通过runqueue结构体获取当前正在运行进程的描述符。并把它赋值给prev。
    (2)判断当前进程是否存在挂起的信号,如果有挂起的信号,那么保持当前进程为running状态,避免反复睡眠唤醒的资源消耗,否则当前进程制定dequeue操作进入休眠状态,并且判断当前进程是否为一个worker,如果是则在workqueue中查看是否有需要被唤醒的worker。
    (3)经过前面的逻辑后判断当前进程prev是否依然存在于runqueue队列中,如果存在说明它并没有休眠下去,那么此时需要执行update_rq_clock,为什么休眠的进程就可以跳过此步,那是因为在休眠dequeue的时候会执行此步骤。
    (4)执行pick_next_task选择下一个要执行的进程next,这一步实际上会根据sched_class类型的不同调用不同的回调,而不同的调度器实现的目的只有一个就是根据自己的算法找到下一个需要调度的进程。
    (5)清除prev进程的tif_need_resched标志
    (6)清除prev进程的preempt标志,清除禁止抢占标志
    (7)更新runqueue中跟当前进程相关的数据到next进程
    (8)执行context_switch执行上下文切换
    (9)执行post_schedule后续的一些操作,根据不同sched class调用不同的post回调

     static inline struct rq *
     context_switch(struct rq *rq, struct task_struct *prev,
                struct task_struct *next)
     {
         struct mm_struct *mm, *oldmm;
     
         prepare_task_switch(rq, prev, next);
     
         mm = next->mm;
         oldmm = prev->active_mm;
         /*
          * For paravirt, this is coupled with an exit in switch_to to
          * combine the page table reload and the switch backend into
          * one hypercall.
          */
         arch_start_context_switch(prev);
     
         if (!mm) {
             next->active_mm = oldmm;
             atomic_inc(&oldmm->mm_count);
             enter_lazy_tlb(oldmm, next);
         } else
             switch_mm(oldmm, mm, next);
     
         if (!prev->mm) {
             prev->active_mm = NULL;
             rq->prev_mm = oldmm;
         }
         /*
          * Since the runqueue lock will be released by the next
          * task (which is an invalid locking op but in the case
          * of the scheduler it's an obvious special-case), so we
          * do an early lockdep release here:
          */
         spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
     
         context_tracking_task_switch(prev, next);
         /* Here we just switch the register state and the stack. */
         switch_to(prev, next, prev);
         barrier();
     
         return finish_task_switch(prev);
     }
    
    

    context_switch函数是用于执行进程切换的,它的主要任务有:
    (1)切换两个进程的虚拟地址空间,切换内存页表,通过函数switch_mm实现
    (2)保存prev进程的栈信息和寄存器信息,然后恢复next进程栈信息和寄存器信息,通过switch_to实现
    (3)prepare_task_switch和finish_task_switch成对出现,用于准备和清理进程切换相关的数据结构

    • 内存空间切换
    	if (!mm) {
             next->active_mm = oldmm;
             atomic_inc(&oldmm->mm_count);
             enter_lazy_tlb(oldmm, next);
         } else
             switch_mm(oldmm, mm, next);
     
         if (!prev->mm) {
             prev->active_mm = NULL;
             rq->prev_mm = oldmm;
         }
    

    这部分之所以区分mm是否为空,主要是区分处理内核线程的,内核线程的mm为空,改用active_mm作为内存管理,其中包含了内核页表。对于mm为空的情况,直接把active_mm 设置为prev->active_mm,这就是设置的内核线程的地址空间。而对于用户进程,active_mm就被设置为等于mm,这一步是在fork的时候做的。
    针对内核线程不用执行switch_mm,因为内核页表都应该是一样的,从而减少了开销。

    • CPU寄存器和栈切换
    #define switch_to(prev, next, last)                 \
        do {                                \
            ((last) = __switch_to((prev), (next)));         \
        } while (0)
    
    

    __switch_to是平台相关的实现,主要实现思想如下:
    (1)先把当前进程的所有寄存器信息和栈信息(sp寄存器)存入当前进程的stack中
    (2)从next进程中去除所有的寄存器信息以及栈信息(sp寄存器)

    current进程的更新

    register unsigned long current_stack_pointer asm ("sp");
     
    static inline struct thread_info *current_thread_info(void)
    {
        return (struct thread_info *)
            (current_stack_pointer & ~(THREAD_SIZE - 1));
    }
    
    
    #define get_current() (current_thread_info()->task)
    #define current get_current()
    

    每个进程都会有两个堆栈,这里我们只关注内核栈,内核预留了一部分空间作为每个进程的内核栈,

    union thread_union {
        struct thread_info thread_info;
        unsigned long stack[THREAD_SIZE/sizeof(long)];
    };
    
    

    thread_info存放在预留空间stack的低地址位置。而stack高地址位置是内核栈底,sp寄存器是栈顶,内核栈是递减向下栈。

    展开全文
  • python中schedule模块的使用

    万次阅读 2016-05-19 11:21:27
    schedulepython中schedule模块的使用由于需要用到一个使用python进行job管理的模块,找到了schedule模块,简单好用,在这里记录一下。

    python中schedule模块的使用

    标签(空格分隔): python job管理 schedule


    python中schedule模块的使用

    由于需要用到一个使用python进行job管理的模块,找到了schedule模块,简单好用,在这里记录一下。
    详细源码可以参考这里

    安装方法

    pip install schedule

    使用方法

    import schedule
    import time
    
    def job():
        print("I'm working...")
    
    schedule.every(10).minutes.do(job)
    schedule.every().hour.do(job)
    schedule.every().day.at("10:30").do(job)
    schedule.every().monday.do(job)
    schedule.every().wednesday.at("13:15").do(job)
    
    while True:
        schedule.run_pending()
        time.sleep(1)

    运行该程序之后,可以定时的进行执行。除了代码中提到的方法之外,还有例如seconds等的一些方法,可以参考源码。

    TIPS

    注意,schedule方法是串行的,也就是说,如果各个任务之间时间不冲突,那是没问题的;如果时间有冲突的话,会串行的执行命令,例如以下代码

    import schedule
    import time
    import threading
    
    def job():
        print("I'm working... in job1  start")
        time.sleep(15)
        print("I'm working... in job1  end")
    
    def job2():
        print("I'm working... in job2")
    
    schedule.every(10).seconds.do(job)
    schedule.every(10).seconds.do(job2)
    
    while True:
        schedule.run_pending()
        time.sleep(1)

    输出如下:

    I’m working… in job1 start
    I’m working… in job1 end
    I’m working… in job2

    可以改成多线程的方式:

    import schedule
    import time
    import threading
    
    def job():
        print("I'm working... in job1  start")
        time.sleep(15)
        print("I'm working... in job1  end")
    
    def job2():
        print("I'm working... in job2")
    
    def run_threaded(job_func):
         job_thread = threading.Thread(target=job_func)
         job_thread.start()
    
     schedule.every(10).seconds.do(run_threaded,job)
     schedule.every(10).seconds.do(run_threaded,job2)
    
    
    while True:
        schedule.run_pending()
        time.sleep(1)

    有如下输出:

    I’m working… in job1 start
    I’m working… in job2
    I’m working… in job1 start
    I’m working… in job2
    I’m working… in job1 end

    可见在并行的执行。
    如果想要对线程的数量有所控制,“If you want tighter control on the number of threads use a shared jobqueue and one or more worker threads”,则可以采用如下方法:

    import Queue
    import time
    import threading
    import schedule
    
    
    def job():
        print("I'm working")
    
    
    def worker_main():
        while 1:
            job_func = jobqueue.get()
            job_func()
    
    jobqueue = Queue.Queue()
    
    schedule.every(10).seconds.do(jobqueue.put, job)
    schedule.every(10).seconds.do(jobqueue.put, job)
    schedule.every(10).seconds.do(jobqueue.put, job)
    schedule.every(10).seconds.do(jobqueue.put, job)
    schedule.every(10).seconds.do(jobqueue.put, job)
    
    worker_thread = threading.Thread(target=worker_main)
    worker_thread.start()
    
    while 1:
        schedule.run_pending()
        time.sleep(1)
    展开全文
  • Python3学习(八):使用schedule模块定时执行任务

    万次阅读 多人点赞 2019-04-12 14:07:33
    python中有一个轻量级的定时任务调度的库:schedule。他可以完成每分钟,每小时,每天,周几,特定日期的定时任务。因此十分方便我们执行一些轻量级的定时任务。 代码如下: import schedule import time def ...

    python中有一个轻量级的定时任务调度的库:schedule。他可以完成每分钟,每小时,每天,周几,特定日期的定时任务。因此十分方便我们执行一些轻量级的定时任务。

    代码如下:

    import schedule
    import time
     
    def job():
        print("I'm working...")
     
    schedule.every(10).minutes.do(job)
    schedule.every().hour.do(job)
    schedule.every().day.at("10:30").do(job)
    schedule.every(5).to(10).days.do(job)
    schedule.every().monday.do(job)
    schedule.every().wednesday.at("13:15").do(job)
     
    while True:
        schedule.run_pending()
        time.sleep(1)

    上面的意思就是:

    每隔十分钟执行一次任务

    每隔一小时执行一次任务

    每天的10:30执行一次任务

    每隔5到10天执行一次任务 

    每周一的这个时候执行一次任务

    每周三13:15执行一次任务

    run_pending:运行所有可以运行的任务

     

    当然,如果函数中带有参数怎么办呢?

    很简单,如下所示:

    import schedule
    import time
     
    def job(name):
        print("her name is : ", name)
    
    name = xiaona
    schedule.every(10).minutes.do(job, name)
    schedule.every().hour.do(job, name)
    schedule.every().day.at("10:30").do(job, name)
    schedule.every(5).to(10).days.do(job, name)
    schedule.every().monday.do(job, name)
    schedule.every().wednesday.at("13:15").do(job, name)
     
    while True:
        schedule.run_pending()
        time.sleep(1)

     

    疑问解答:

    最近有人问我while True之类的是什么意思,很简单,如果你去掉while True这个死循环的话,schedule.run_pending()是没有办法持续运行的,那么schedule.run_pending()是个什么东西呢——

    schedule其实就只是个定时器。在while True死循环中,schedule.run_pending()是保持schedule一直运行,去查询上面那一堆的任务,在任务中,就可以设置不同的时间去运行。跟linux中设置crontab定时任务是类似的。

    所以,schedule有一定的局限性,所以只能用来执行一些小型的定时任务,它的局限性在哪呢——

    1.需要定时运行的函数job不应当是死循环类型的,也就是说,这个线程应该有一个执行完毕的出口。一是因为线程万一僵死,会是非常棘手的问题;二是下一次定时任务还会开启一个新的线程,执行次数多了就会演变成灾难。

    2.如果schedule的时间间隔设置得比job执行的时间短,一样会线程堆积形成灾难,也就是说,我job的执行时间是1个小时,但是我定时任务设置的是5分钟一次,那就会一直堆积线程。

    展开全文
  • 定时任务schedule的二种用法

    千次阅读 2017-10-15 00:04:11
    schedule(TimerTask task, long delay); schedule(TimerTask task, long delay, long period); 第一个参数TimerTask 类,使用时要继承该类,由于 TimerTask 类 实现了 Runnable 接口,要实现public void run...
  • 我们经常在创建线程执行函数/worker执行函数,定时器执行函数等等情况下,会经常看到schedule函数的调用,这是进程上下文,还有中断上下文的调度,即preempt_schedule_irq.另外我们在进程调度的时候会看到是否需要设置...
  • Schedule

    2019-06-06 16:49:05
    import schedule def job(name): print("her name is : ", name) name = 'xiaona' schedule.every(10).seconds.do(job,name) #每隔10秒 schedule.every(10).minutes.do(job, name) # 每隔十分钟执行一次任务 ...
  • schedule 详解

    千次阅读 2017-10-31 16:52:20
    mmidd CnBlogsHomeNew PostContactAdminRss Posts - 9 Articles - 0 Comments - 34  Cocos2d-X3.0 刨根问底(六)--...上一章,我们分析Node类的源码,在Node类里面耦合了一个
  • Spring中@schedule的简单使用

    万次阅读 2018-09-28 14:52:52
    在springMVC里使用spring的定时任务非常的简单,如下: (一)在xml里加入task的命名空间 xmlns:task="http://www.springframework.org/schema/task" ...
  • Java定时任务Schedule实现的4种方式

    万次阅读 2019-02-28 08:38:20
    java实现定时任务 Schedule https://blog.csdn.net/java_2017_csdn/article/details/78060204 2017年09月22日 10:30:52Java_2017_csdn阅读数:3306 java实现定时任务 Schedule 标签:java实现定时任务 Schedule...
  • TVM之Schedule

    千次阅读 2019-07-07 00:36:48
    TVM之Schedule1. schedule2. stage3. methods for stage3.1 split3.2 tile3.3 fuse3.4 reorder3.5 bind3.6 compute_at3.7 compute_inline3.8 compute_root 最近在阅读TVM官网的文档,在阅读的过程中将keywords以及...
  • spring schedule定时任务(一):注解的方式

    万次阅读 热门讨论 2020-10-14 14:35:59
    1、spring schedule注解的方式; 2、spring schedule配置文件的方式; 3、java类继承TimerTask; 第一种方式的实现: 1、使用maven创建spring项目,schedule在spring-context.jar的包下边,因此需要导入与之相关...
  • java实现定时任务 Schedule

    万次阅读 多人点赞 2016-06-07 11:59:05
    java实现定时任务 Schedule
  • [kubernetes] Schedule --- Node调度与隔离

    千次阅读 2019-06-06 12:04:39
    目录 1. NodeSelector 2. 亲和与反亲和 Affinity and Anti-affinity 节点Node 亲和性 pod 亲和性和反亲和性 3. 污点(Taints)与容忍(tolerations) 1、设置污点: ...如果需要限制Pod到...
  • JAVA动态任务SCHEDULEJOB

    千次阅读 2017-03-15 17:20:53
    一、ScheduleJob实体类介绍   public class ScheduleJob implements Serializable {  public static String STATUS_RUNNING = "1";  public static final String STATUS_NOT_RUNNING = "0";  public ...
  • scheduleJob

    千次阅读 2016-08-26 16:36:37
    首先看AndroidManifest文件    android:icon="@drawable/ic_launcher"  android:label="@string/app_name"  android:theme="@style/AppTheme" >    android:name=".Mai
  • SCHEDULE

    2019-09-02 13:13:31
    schedule.rar ...
  • Schedule用法实例

    千次阅读 2015-11-09 13:57:17
    一、包 import org.quartz.CronTrigger; import org.quartz.DateBuilder; import org.quartz.JobBuilder; import org.quartz.JobDataMap; import org.quartz.JobDetail;...import org.quartz.JobExecutionContext;...
  • linux schedule 理解

    千次阅读 2018-01-08 14:41:49
    Linux内核进程调度schedule深入理解   一.说明 本文以linux-2.4.10 为例主要分析Linux 进程调度模块中的schedule 函数及其相关的函数。另外相关的前提知识也会说明。默认系统平台是自己的i386 架构的...
  • python任务调度之schedule

    千次阅读 2018-08-26 14:18:12
    import schedule import time def job(): print("I'm working...") schedule.every(10).minutes.do(job) schedule.every().hour.do(job) schedule.every().day.at("10:30").do(job) sch...
1 2 3 4 5 ... 20
收藏数 180,929
精华内容 72,371
关键字:

schedule