Linux 新的API signalfd、timerfd、eventfd使用说明

2019-10-13 18:39:40王振洲

L17-L21:将感兴趣的信号加入到sigset_t中;

L24:调用signalfd,把信号集与fd关联起来,第一个参数为-1表示新建一个signalfd,不是-1并且是一个合法的signalfd表示向其添加新的信号。

L29:阻塞等待信号的发生并读取。根据读取的结果可以知道发生了什么信号。

timerfd涉及的API

#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);
#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;返回的fd可以进行如下操作:read、select(poll、epoll)、close
timerfd_settime:设置timer的周期,以及起始间隔
timerfd_gettime:获取到期时间。
//函数参数中数据结构如下: 
struct timespec 
{ 
time_t tv_sec; /* Seconds */ 
long tv_nsec; /* Nanoseconds */ 
}; 
struct itimerspec 
{ 
struct timespec it_interval; /* Interval for periodic timer */ 
struct timespec it_value; /* Initial expiration */ 
};
//函数参数中数据结构如下: 
struct timespec 
{ 
time_t tv_sec; /* Seconds */ 
long tv_nsec; /* Nanoseconds */ 
}; 
struct itimerspec 
{ 
struct timespec it_interval; /* Interval for periodic timer */ 
struct timespec it_value; /* Initial expiration */ 
};

l例子

#include <sys/timerfd.h> 
#include <sys/time.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 { perror(msg); exit(EXIT_FAILURE); } while (0) 
void printTime() 
{ 
struct timeval tv; 
gettimeofday(&tv, NULL); 
printf("printTime: current time:%ld.%ld ", tv.tv_sec, tv.tv_usec); 
} 
int main(int argc, char *argv[]) 
{ 
struct timespec now; 
if (clock_gettime(CLOCK_REALTIME, &now) == -1) 
handle_error("clock_gettime"); 
struct itimerspec new_value; 
new_value.it_value.tv_sec = now.tv_sec + atoi(argv[1]); 
new_value.it_value.tv_nsec = now.tv_nsec; 
new_value.it_interval.tv_sec = atoi(argv[2]); 
new_value.it_interval.tv_nsec = 0; 
int 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"); 
printTime(); 
printf("timer startedn"); 
for (uint64_t tot_exp = 0; tot_exp < atoi(argv[3]);) 
{ 
uint64_t exp; 
ssize_t s = read(fd, &exp, sizeof(uint64_t)); 
if (s != sizeof(uint64_t)) 
handle_error("read"); 
tot_exp += exp; 
printTime(); 
printf("read: %llu; total=%llun",exp, tot_exp); 
} 
exit(EXIT_SUCCESS); 
}
#include <sys/timerfd.h> 
#include <sys/time.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 { perror(msg); exit(EXIT_FAILURE); } while (0) 
void printTime() 
{ 
struct timeval tv; 
gettimeofday(&tv, NULL); 
printf("printTime: current time:%ld.%ld ", tv.tv_sec, tv.tv_usec); 
} 
int main(int argc, char *argv[]) 
{ 
struct timespec now; 
if (clock_gettime(CLOCK_REALTIME, &now) == -1) 
handle_error("clock_gettime"); 
struct itimerspec new_value; 
new_value.it_value.tv_sec = now.tv_sec + atoi(argv[1]); 
new_value.it_value.tv_nsec = now.tv_nsec; 
new_value.it_interval.tv_sec = atoi(argv[2]); 
new_value.it_interval.tv_nsec = 0; 
int 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"); 
printTime(); 
printf("timer startedn"); 
for (uint64_t tot_exp = 0; tot_exp < atoi(argv[3]);) 
{ 
uint64_t exp; 
ssize_t s = read(fd, &exp, sizeof(uint64_t)); 
if (s != sizeof(uint64_t)) 
handle_error("read"); 
tot_exp += exp; 
printTime(); 
printf("read: %llu; total=%llun",exp, tot_exp); 
} 
exit(EXIT_SUCCESS); 
}