1. 定时: 一般是通过在当前 jiffies 上加上一个 delay 得到目标 jiffies ,然后比较目标 jiffies 实现定时。
2. 延时: 短延时(一般通过忙等待实现),长延时(一般通过使进程让出处理器的方式实现) 。
3. 系统中记录时间的计数器:(1) jiffies ,(2) 处理器特定的寄存器
4. 内核定时器: 内核定时器常常作为"软件中断"而异步运行。
实例:参考ldd3
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//jittimer.c //#include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/init.h> #include <linux/time.h> #include <linux/timer.h> #include <linux/kernel.h> #include <linux/proc_fs.h> #include <linux/types.h> #include <linux/spinlock.h> #include <linux/interrupt.h> #include <asm/hardirq.h> /* * This module is a silly one: it only embeds short code fragments * that show how time delays can be handled in the kernel. */ int delay = HZ; /* the default delay, expressed in jiffies */ MODULE_AUTHOR("Alessandro Rubini"); MODULE_LICENSE("Dual BSD/GPL"); /* * The timer example follows */ int tdelay = 10; module_param(tdelay, int, 0); /* This data structure used as "data" for the timer and tasklet functions */ struct jit_data { struct timer_list timer; wait_queue_head_t wait; unsigned long prevjiffies; unsigned char *buf; int loops; }; #define JIT_ASYNC_LOOPS 5 void jit_timer_fn(unsigned long arg) { struct jit_data *data = (struct jit_data *)arg; unsigned long j = jiffies; data->buf += sprintf(data->buf, "%9li %3li %i %6i %i %s ", j, j - data->prevjiffies, in_interrupt() ? 1 : 0, current->pid, smp_processor_id(), current->comm); if (--data->loops) { data->timer.expires += tdelay; data->prevjiffies = j; add_timer(&data->timer); } else { wake_up_interruptible(&data->wait); } } /* the /proc function: allocate everything to allow concurrency */ int jit_timer(char *buf, char **start, off_t offset, int len, int *eof, void *unused_data) { struct jit_data *data; char *buf2 = buf; unsigned long j = jiffies; data = kmalloc(sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; init_timer(&data->timer); init_waitqueue_head (&data->wait); /* write the first lines in the buffer */ buf2 += sprintf(buf2, " time delta inirq pid cpu command "); buf2 += sprintf(buf2, "%9li %3li %i %6i %i %s ", j, 0L, in_interrupt() ? 1 : 0, current->pid, smp_processor_id(), current->comm); /* fill the data for our timer function */ data->prevjiffies = j; data->buf = buf2; data->loops = JIT_ASYNC_LOOPS; /* register the timer */ data->timer.data = (unsigned long)data; data->timer.function = jit_timer_fn; data->timer.expires = j + tdelay; /* parameter */ add_timer(&data->timer); /* wait for the buffer to fill */ wait_event_interruptible(data->wait, !data->loops); if (signal_pending(current)) return -ERESTARTSYS; buf2 = data->buf; kfree(data); *eof = 1; return buf2 - buf; } int __init jit_init(void) { create_proc_read_entry("jitimer", 0, NULL, jit_timer, NULL); return 0; /* success */ } void __exit jit_cleanup(void) { remove_proc_entry("jitimer", NULL); } module_init(jit_init); module_exit(jit_cleanup);
程序主要通过定时器组织起来,注册定时器后主程序休眠,等待唤醒。当读取次数到达时,通过唤醒等待队列使程序退出。