在用户提供的时间每天在Linux内核模块中调度任务

时间:2021-12-24 02:12:17

I am writing a linux kernel module which schedules a task using schedule_delayed_work at a particular time which in turn send a signal to a user space program to do some task. What I did is manually given the time in milliseconds (say 5000ms) and changed it to jiffies using "msec to jiffies" function and tested it and worked.

我正在编写一个linux内核模块,该模块在特定时间使用schedule_delayed_work来调度任务,该特定时间又向用户空间程序发送信号以执行某项任务。我所做的是手动给出时间(以毫秒为单位)(比如5000毫秒),并使用“msec to jiffies”功能将其更改为jiffies并对其进行测试和工作。

My use case is that the user will give a time (say 5 pm) and the module has to schedule it to send the signal everyday at 5 pm to the user program. I am totally confused in how to calculate the milliseconds from the user given time for everyday basis.

我的用例是用户将给出一个时间(比如说下午5点),并且模块必须安排它在每天下午5点向用户程序发送信号。我完全很困惑如何计算用户每天给定时间的毫秒数。

I used workqueue to create a queue and then the task to accomplish and doing the scheduling.

我使用workqueue创建一个队列,然后完成任务并完成调度。

My kernel module:

我的内核模块:

    static void wq_handler_function(struct work_struct *work);
    static unsigned long delay;

    static struct workqueue_struct *my_wq; // my workqueue
    static DECLARE_DELAYED_WORK(my_work, wq_handler_function); //my work/task


    static void wq_handler_function(struct work_struct *work)
    {
       printk(KERN_DEBUG "handler function called\n");
       if(my_wq)
       {
          /*Do some work like sending signal to user space*/
          schedule_delayed_work(&my_work, delay); /*reschedule after the first scheduled time finished*/
       }
    }

    int sig_init_module(void)
    {
       printk(KERN_DEBUG "signal module initiated\n");
       delay = msecs_to_jiffies(5000); //Manually given 5000ms (5 sec) for scheuling
       if(!my_wq)
          my_wq = create_workqueue("my_queue");

          if(my_wq)
          {
             schedule_delayed_work(&my_work, delay); /*schedule for the first time while module initiates*/
          }
        return 0;
     }

     void sig_cleanup_module(void)
     {
        flush_scheduled_work();
        cancel_delayed_work_sync(&my_work);

        flush_workqueue(my_wq);
        destroy_workqueue(my_wq);

        printk(KERN_DEBUG "signal module removed\n");
     }

     module_init(sig_init_module);
     module_exit(sig_cleanup_module);

Kindly help me to have a solution for this. Thanks in advance!!!.

请帮我解决这个问题。提前致谢!!!。

2 个解决方案

#1


3  

I don't understand why kernel modification would be desirable or necessary. If you want something periodically done (e.g. log rotation), add it to cron. Another option would be to use timerfd.

我不明白为什么内核修改是可取的或必要的。如果您想要定期完成某些操作(例如日志轮换),请将其添加到cron。另一种选择是使用timerfd。

#2


-1  

use mktime() function in kernel code which takes the wall time as arguments and directly returns the jiffies value. For info about mktime, see this http://www.makelinux.net/ldd3/chp-7-sect-2

在内核代码中使用mktime()函数,它将wall time作为参数并直接返回jiffies值。有关mktime的信息,请参阅http://www.makelinux.net/ldd3/chp-7-sect-2

#1


3  

I don't understand why kernel modification would be desirable or necessary. If you want something periodically done (e.g. log rotation), add it to cron. Another option would be to use timerfd.

我不明白为什么内核修改是可取的或必要的。如果您想要定期完成某些操作(例如日志轮换),请将其添加到cron。另一种选择是使用timerfd。

#2


-1  

use mktime() function in kernel code which takes the wall time as arguments and directly returns the jiffies value. For info about mktime, see this http://www.makelinux.net/ldd3/chp-7-sect-2

在内核代码中使用mktime()函数,它将wall time作为参数并直接返回jiffies值。有关mktime的信息,请参阅http://www.makelinux.net/ldd3/chp-7-sect-2