linux手册翻译——timerfd_create(2)

linux手册翻译——timerfd_create(2),第1张

timerfd_create, timerfd_settime, timerfd_gettime - timers that notify via file descriptors

这些系统调用创建并 *** 作一个计时器,计时器通过文件描述符来通知计时到期,这样就可以通过 select(2)、poll(2) 和 epoll(7) 监视文件描述符从而监听计时器。

这三个系统调用的使用类似于 timer_create(2)、timer_settime(2) 和 timer_gettime(2) 。 (没有与timer_getoverrun(2) 类似的系统调用,因为该功能由 read(2) 提供,如下所述。)

int timerfd_create(int clockid, int flags)

timerfd_create() 创建一个新的计时器对象,并返回引用该计时器的文件描述符。 clockid 参数指定使用那种类型的时钟(clock)来实现计时器(timer),并且必须是以下之一:

有关上述时钟的更多详细信息,请参阅clock_getres(2)。

可以使用clock_gettime(2) 获取每个时钟的当前值。

从 Linux 2.6.27 开始,可以在标志中对以下值进行按位 OR 运算以更改 timerfd_create() 的行为:

在 2.6.26 及包括 2.6.26 的 Linux 版本中,标志必须指定为零。

int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itimerspec *old_value)

timerfd_settime() arms (starts) or disarms (stops) the timer referred to by the file descriptor fd.

new_value 参数指定计时器的初始到期时间和到期间隔(换句话说,计时器开始执行后,将会在到达初始到期时间时报告一次,此后每过一个到期间隔就会报告一次)。 用于此参数的 itimerspec 结构包含两个字段,每个字段又是一个 timespec 类型的结构:

new_value.it_value 指定计时器的初始到期时间,以秒和纳秒为单位。 将 new_value.it_value 的任一字段设置为非零值,即可启动计时器。 将 new_value.it_value 的两个字段都设置为零会解除定时器。

将 new_value.it_interval 的一个或两个字段设置为非零值指定初始到期后重复计时器到期的时间段(以秒和纳秒为单位)。 如果 new_value.it_interval 的两个字段都为零,则计时器仅在 new_value.it_value 指定的时间到期一次。

如果将 new_value 设置为(10S,2S),即表示,计时器启动后,将会在10S后报告一次,然后每隔2S报告一次;

如果将 new_value 设置为(10S,0S),即表示,计时器启动后,将会在10S后报告一次,然后就不再报告了;

如果将 new_value 修改为(0S,0S),即表示,停止计时。

默认情况下, new_value 中指定的初始到期时间是相对于调用时计时器时钟上的当前时间的(即,new_value.it_value 是相对于 clockid 指定的时钟的当前值设置的)。 可以通过 flags 参数指定使用绝对时间。

flags 参数是一个位掩码,可以包含以下值:

如果 old_value 参数不为 NULL,则它指向的 itimerspec 结构用于返回调用时当前计时器的设置; 请参阅下面的 timerfd_gettime() 说明。

int timerfd_gettime(int fd, struct itimerspec *curr_value)

timerfd_gettime() 在 curr_value 中返回一个 itimerspec 结构,该结构包含文件描述符 fd 所引用的计时器的当前设置。

it_value 字段返回计时器下一次到期之前的时间量。 如果此结构的两个字段都为零,则定时器当前已解除。 无论在设置计时器时是否指定了 TFD_TIMER_ABSTIME 标志,该字段始终包含一个相对值。

it_interval 字段返回定时器的间隔。 如果此结构的两个字段都为零,则计时器设置为仅在 curr_value.it_value 指定的时间到期一次。

timerfd_create() 返回的文件描述符支持以下附加 *** 作:

在 fork(2) 之后,子进程继承了 timerfd_create() 创建的文件描述符的副本。 文件描述符引用与父级中相应文件描述符相同的底层计时器对象,子级中的 read(2) 将返回有关计时器到期的信息。

A file descriptor created by timerfd_create() is preserved across execve(2), and continues to generate timer expirations if the timer was armed.

成功时, timerfd_create() 返回一个新的文件描述符。 出错时,返回 -1 并设置 errno 以指示错误。

timerfd_settime() 和 timerfd_gettime() 成功返回 0; 出错时返回 -1,并设置 errno 以指示错误。

timerfd_create() can fail with the following errors:

timerfd_settime() and timerfd_gettime() can fail with the following errors:

timerfd_settime() can also fail with the following errors:

These system calls are available on Linux since kernel 2.6.25.

Library support is provided by glibc since version 2.8.

These system calls are Linux-specific.

假设在使用 timerfd_create() 创建的 CLOCK_REALTIME 或 CLOCK_REALTIME_ALARM 计时器时,发生以下场景:

在这种情况下,会发生以下情况:

目前,timerfd_create() 支持的时钟 ID 类型少于 timer_create(2)。

以下程序创建一个 基于实时时钟的绝对时间 的计时器,然后监控其进度。 该程序最多接受三个命令行参数。 第一个参数指定计时器初始到期的秒数。 第二个参数指定计时器的间隔,以秒为单位。 第三个参数指定程序在终止前应允许计时器到期的次数。 第二个和第三个命令行参数是可选的。

以下 shell 会话演示了该程序的使用:

时事件,void(*handle)(union sigval v)参数就是处理事件的函数指针。

int omsSetTimer(timer_t *tId,int value,int interval)就是设置定时器。

按你说的,如果要同时起多个定时器,需要定义一个数组timer_t tm[n]int it[n]tm就是定时器结构,it用来记录对应的定时器是否已经使用,使用中的就是1,没用的就是0;

主进程消息来了就从it找一个没用的来omsSetTimer,如果收到终止消息,那omsSetTimer 定时时间为0

int omsTimer(timer_t *tId,int iValue,int iSeconds ,void(*handle)(union sigval v),void * param)

{

struct sigevent se

struct itimerspec ts

memset (&se, 0, sizeof (se))

se.sigev_notify = SIGEV_THREAD

se.sigev_notify_function = handle

se.sigev_value.sival_ptr = param

if (timer_create (CLOCK_REALTIME, &se, tId) <0)

{

return -1

}

ts.it_value.tv_sec = iValue

// ts.it_value.tv_sec =3

//ts.it_value.tv_nsec = (long)(iValue % 1000) * (1000000L)

ts.it_value.tv_nsec = 0

ts.it_interval.tv_sec = iSeconds

//ts.it_interval.tv_nsec = (long)(iSeconds % 1000) * (1000000L)

ts.it_interval.tv_nsec = 0

if (timer_settime(*tId, TIMER_ABSTIME, &ts, NULL) <0)

{

return -1

}

return 0

}

int omsSetTimer(timer_t *tId,int value,int interval)

{

struct itimerspec ts

ts.it_value.tv_sec =value

//ts.it_value.tv_nsec = (long)(value % 1000) * (1000000L)

ts.it_value.tv_nsec = 0

ts.it_interval.tv_sec = interval

//ts.it_interval.tv_nsec = (long)(interval % 1000) * (1000000L)

ts.it_interval.tv_nsec = 0

if (timer_settime(*tId, TIMER_ABSTIME, &ts, NULL) <0)

{

return -1

}

return 0

}

另外,团IDC网上有许多产品团购,便宜有口碑


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/8613629.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-18
下一篇 2023-04-18

发表评论

登录后才能评论

评论列表(0条)

保存