我遇到以下代码问题。 每当我调用ioctl REGISTER时,计时器就会启动,当它到期时,它调用“update”来调度使用工作队列的任务,doJob方法只是用新的到期时间更新计时器。
当我调用ioctl UNREGISTER时,计时器被终止...但它继续调用更新(从而更新其到期时间)。为什么定时器在调用ioctl UNREGISTER后没有停止?
int time = 1;
module_param(time, int, 0644);
int delay;
struct workqueue_struct* wq;
struct work_struct task;
struct timer_list timer; /* timer */
long ioctl(struct file *filp, unsigned int cmd, unsigned long args) {
switch (cmd) {
case REGISTER:
add_timer(&timer);
return 0;
case UNREGISTER:
del_timer_sync(&timer);
return 0;
}
}
static void doJob(struct work_struct *work) {
printk(KERN_EMERG "\ndoJob\n");
mod_timer(&timer, jiffies + delay);
}
void update(unsigned long arg) {
queue_work(wq, &task);
}
struct file_operations fop = {
.owner = THIS_MODULE,
.unlocked_ioctl = ioctl
};
static struct miscdevice dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "timer",
.fops = &fop
};
static int __init init(void)
{
delay = HZ * time / 1000;
if (delay < 1) {
printk(KERN_EMERG "time param is too small\n");
return -1;
}
init_timer(&timer);
timer.data = 0;
timer.function = update;
timer.expires = jiffies + delay;
if (misc_register(&dev) < 0) {
printk(KERN_EMERG "error registering misc device\n");
return -1;
}
wq = create_workqueue("timer_task");
INIT_WORK(&task, doJob);
return 0;
}
static void __exit fini(void)
{
misc_deregister(&dev);
printk(KERN_EMERG "deregistered\n");
}
module_init(init);
module_exit(fini);
答案 0 :(得分:2)
del_timer_sync()
的{{3}}说:
Callers must prevent restarting of the timer, otherwise this function is meaningless.
换句话说,del_timer_sync()
等待处理程序退出,但如果该处理程序重新安排计时器,那么下次它将很高兴再次运行。
您需要做的就是维护另一个变量timer_active
。在启动计时器之前将其设置为true,在删除计时器之前将其设置为false。然后仅在timer_active
为真时重新安排计时器。通过该订单,您可以确保在del_timer_sync()
返回后不再运行计时器。