# 定时器timerfd 相关函数
#include <sys/timerfd.h>
int timerfd_create(int clockid, int flags);
int timerfd_settime(int fd, int flags,
const struct itimerspec *new_value,
struct itimerspec *old_value);
int timerfd_gettime(int fd, struct itimerspec *curr_value);
timerfd_create#
| timerfd_create() | 创建一个定时器描述付timerfd |
|---|
| clockid | CLOCK_REALTIME、CLOCK_MONOTONIC |
| flags | 为 0 或者 O_NONBLOCK |
CLOCK_REALTIME //自1970-01-01起经历的秒数、本秒中经历的纳秒数
CLOCK_MONOTONIC //自CPU启动时流逝的时间
timetfd_settime#
| timerfd_settime | 用来启动或关闭fd指定的定时器 |
|---|
| fd | timerfd_create函数返回的定时器文件描述符 |
| flags | 1 代表绝对时间,0 为相对时间 |
| new_value | 指定新的超时时间 |
| old_value | 不为 NULL,则返回定时器这这次设置之前的超时时间 |
timerfd_gettime#
| timerfd_gettime | 这个函数通常是为了检查定时器还有多长时间触发,或者检查定时器是否是一次性的还是周期性的。周期性定时器的it_interval会被设置为非零值,表示每次到期后,定时器会自动重新设置为这个间隔值。如果it_interval为零,则定时器只触发一次。 |
|---|
示例程序#
#include <sys/timerfd.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h> /* Definition of uint64_t */
#define handle_error(msg) \
do { printf(msg); exit(EXIT_FAILURE); } while (0)
static void print_elapsed_time(void)
{
static struct timespec start;
struct timespec curr;
static int first_call = 1;
int secs, nsecs;
if (first_call)
{
first_call = 0;
if (clock_gettime(CLOCK_MONOTONIC, &start) == -1)
handle_error("clock_gettime");
}
if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1)
handle_error("clock_gettime");
secs = curr.tv_sec - start.tv_sec;
nsecs = curr.tv_nsec - start.tv_nsec;
if (nsecs < 0)
{
secs--;
nsecs += 1000000000;
}
printf("%d.%03d: ", secs, (nsecs + 500000) / 1000000);
}
int main(int argc, char *argv[])
{
struct itimerspec new_value;
int max_exp, fd;
struct timespec now;
uint64_t exp, tot_exp;
ssize_t s;
if ((argc != 2) && (argc != 4))
{
ssize_t s;
printf("%s %d\n",__FUNCTION__, __LINE__);
if ((argc != 2) && (argc != 4))
{
fprintf(stderr, "%s init-secs [interval-secs max-exp]\n", argv[0]);
handle_error("argc argv is error");
}
}
if (clock_gettime(CLOCK_REALTIME, &now) == -1)
{
handle_error("clock_gettime");
}
/* Create a CLOCK_REALTIME absolute timer with initial
expiration and interval as specified in command line */
new_value.it_value.tv_sec = now.tv_sec + atoi(argv[1]);
new_value.it_value.tv_nsec = now.tv_nsec;
if (argc == 2) {
new_value.it_interval.tv_sec = 0;
max_exp = 1;
} else {
new_value.it_interval.tv_sec = atoi(argv[2]);
max_exp = atoi(argv[3]);
}
new_value.it_interval.tv_nsec = 0;
fd = timerfd_create(CLOCK_REALTIME, 0);
if (fd == -1)
handle_error("timerfd_create");
if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL) == -1)
handle_error("timerfd_settime");
print_elapsed_time();
printf("timer started\n");
for (tot_exp = 0; tot_exp < max_exp;) {
s = read(fd, &exp, sizeof(uint64_t));
if (s != sizeof(uint64_t))
handle_error("read");
tot_exp += exp;
print_elapsed_time();
printf("read: %llu; total=%llu\n",
(unsigned long long) exp,
(unsigned long long) tot_exp);
}
exit(EXIT_SUCCESS);
}