您现在的位置: 万盛学电脑网 >> 操作系统 >> Linux教程 >> 正文

Linux--Linux内核模块编程--替任务调度在线阅读

作者:佚名    责任编辑:admin    更新时间:2022-06-22

 任务调度
  常常的,我们有‘家务管理’的任务需要在某个时间做或者偶尔经常如此。如果任务由进程完成,我们可以将它放在 crontab 文件中。如果任务由内核模块完成,我们有两种可能。第一个是在 crontab 文件中放置一个在必要的时候通过系统调用唤醒模块的进程,例如通过打开文件。这是非常低效的,然而--我们运行一个不在 crontab 中的新进程, 读一个新的可执行的进程到内存,而所有这些只是唤醒在内存中的内核模块。
  替代的,我们可以创建一个对每个定时器中断被调用一次的函数。我们的办法是创建一个包含在 tq_struct结构中的任务,而该结构包含该函数的指针。然后我们使用 queue_task 将那个任务放置在被称为tq_timer 的任务列表中,该列表是在下一个定时器中断将被执行的任务的列表。因为我们我们想该函数在下一次定时器中断时继续被执行,我们需要在它被调用后将它放回 tq_timer。
  这还有一点我们需要记住的。当一个模块被 rmmod 移除时,它的引用计数器首先被检查,如果它为0,module_cleanup 将被调用。然后模块连同它的所有函数被从内存中清除。没有人去检查看在定时器任务列表中是否碰巧包含一个这样的不再可见的函数的指针。一段时间后(从计算机的观点看,而从人的观点看它什么也不是,它少于百分之一秒),内核有了一个定时器中断并试图去调用任务列表中的函数。不幸的,那个函数不在那儿。在大多情况下它刚才所在内存页没有被使用,而你会得到一个难看的错误消息。但是如果别的某些代码现在位于同一个内存位置,事情会变得 非常 难看。不幸的,我们没有一个简单的办法将一个任务从任务列表中注销。
  既然 cleanup_module 不能返回错误代码(它是一个void函数),解决的办法是根本不让它返回。替代的,它调用sleep_on 或 module_sleep_on(他们实际上是相同的。 )使 rmmod 进程睡眠。在此之前,它通过设置一个全局变量通知在定时器中断将被调用的函数停止连接自己。然后,在下一次定时器中断, rmmod进程被唤醒,当我们的函数不再在那个队列中时移除那个模块就是安全的了。