加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

linux 定时器 API

发布时间:2020-12-13 23:13:23 所属栏目:Linux 来源:网络整理
导读:内核提供给驱动许多函数来声明,注册,以及去除内核定时器. 下列的引用展示了基本的 代码块: ? #include linux/timer.h struct timer_list { /* ... */ unsigned long expires; void (*function)(unsigned long); unsigned long data; }; void init_timer(stru

内核提供给驱动许多函数来声明,注册,以及去除内核定时器. 下列的引用展示了基本的 代码块:

?

#include <linux/timer.h> struct timer_list

{

/* ... */

unsigned long expires;

void (*function)(unsigned long); unsigned long data;

};

void init_timer(struct timer_list *timer);

struct timer_list TIMER_INITIALIZER(_function,_expires,_data);

?

void add_timer(struct timer_list * timer); int del_timer(struct timer_list * timer);

?

这个数据结构包含比曾展示过的更多的字段,但是这 3 个是打算从定时器代码自身以外 被存取的. 这个 expires 字段表示定时器期望运行的 jiffies 值; 在那个时间,这个 function 函数被调用使用 data 作为一个参数. 如果你需要在参数中传递多项,你可以 捆绑它们作为一个单个数据结构并且传递一个转换为 unsiged long 的指针,在所有支持 的体系上的一个安全做法并且在内存管理中相当普遍( 如同 15 章中讨论的 ). expires 值不是一个 jiffies_64 项因为定时器不被期望在将来很久到时,并且 64-位操作在 32- 位平台上慢.

?

这个结构必须在使用前初始化. 这个步骤保证所有的成员被正确建立,包括那些对调用者 不透明的. 初始化可以通过调用 init_timer 或者 安排 TIMER_INITIALIZER 给一个静态 结构,根据你的需要. 在初始化后,你可以改变 3 个公共成员在调用 add_timer 前. 为 在到时前禁止一个已注册的定时器,调用 del_timer.

?

jit 模块包括一个例子文件,/proc/jitimer ( 为 "just in timer"),它返回一个头文 件行以及 6 个数据行. 这些数据行表示当前代码运行的环境; 第一个由读文件操作产生 并且其他的由定时器. 下列的输出在编译内核时被记录:

?

phon% cat /proc/jitimer

time delta?? inirq pid?? cpu command 33565837????????? 0? 0? 1269? 0? cat

33565847

10

1

1271

0

sh

33565857

10

1

1273

0

cpp0

33565867

10

1

1273

0

cpp0

33565877

10

1

1274

0

cc1

33565887

10

1

1274

0

cc1

?

在这个输出,time 字段是代码运行时的 jiffies 值,delta 是自前一行的 jiffies 改 变值,inirq 是由 in_interrupt 返回的布尔值,pid 和 command 指的是当前进程,以 及 cpu 是在使用的 CPU 的数目( 在单处理器系统上一直为 0).

?

如果你读 /proc/jitimer 当系统无负载时,你会发现定时器的上下文是进程 0,空闲任 务,它被称为"对换进程"只要由于历史原因.

?

用来产生 /proc/jitimer 数据的定时器是缺省每 10 jiffies 运行一次,但是你可以在 加载模块时改变这个值通过设置 tdelay ( timer delay ) 参数.

?

下面的代码引用展示了 jit 关于 jitimer 定时器的部分. 当一个进程试图读取我们的文 件,我们建立这个定时器如下:

?

unsigned long j = jiffies;

/* 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);

?

The actual timer function looks like this: 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 %sn",

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);

}

}

?

定时器 API 包括几个比上面介绍的那些更多的功能. 下面的集合是完整的核提供的函数 列表:

?

int mod_timer(struct timer_list *timer,unsigned long expires);

?

更新一个定时器的超时时间,使用一个超时定时器的一个普通的任务(再一次,关 马达软驱定时器是一个典型例子). mod_timer 也可被调用于非激活定时器,那里 你正常地使用 add_timer.

?

int del_timer_sync(struct timer_list *timer);

?

如同 del_timer 一样工作,但是还保证当它返回时,定时器函数不在任何 CPU 上 运行. del_timer_sync 用来避免竞争情况在 SMP 系统上,并且在 UP 内核中和 del_timer 相同. 这个函数应当在大部分情况下比 del_timer 更首先使用. 这个 函数可能睡眠如果它被从非原子上下文调用,但是在其他情况下会忙等待. 要十分 小心调用 del_timer_sync 当持有锁时; 如果这个定时器函数试图获得同一个锁,系统会死锁. 如果定时器函数重新注册自己,调用者必须首先确保这个重新注册不 会发生; 这常常同设置一个" 关闭 "标志来实现,这个标志被定时器函数检查.

?

int timer_pending(const struct timer_list * timer);

?

返回真或假来指示是否定时器当前被调度来运行,通过调用结构的其中一个不透明 的成员.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读