三种新的fd加入linux内核的的版本:
  signalfd:2.6.22
  timerfd:2.6.25
  eventfd:2.6.22
  三种fd的意义:
  lsignalfd
  传统的处理信号的方式是注册信号处理函数;由于信号是异步发生的,要解决数据的并发访问,可重入问题。signalfd可以将信号抽象为一个文件描述符,当有信号发生时可以对其read,这样可以将信号的监听放到select、poll、epoll等监听队列中。
  ltimerfd
  可以实现定时器的功能,将定时器抽象为文件描述符,当定时器到期时可以对其read,这样也可以放到监听队列的主循环中。
  leventfd
  实现了线程之间事件通知的方式,也可以用于用户态和内核通信。eventfd的缓冲区大小是sizeof(uint64_t);向其write可以递增这个计数器,read操作可以读取,并进行清零;eventfd也可以放到监听队列中,当计数器不是0时,有可读事件发生,可以进行读取。
  三种新的fd都可以进行监听,当有事件触发时,有可读事件发生。
  signalfd涉及API:
  点击(此处)折叠或打开
  #include <sys/signalfd.h>
  int signalfd(int fd, const sigset_t *mask, int flags);
  参数fd:如果是-1则表示新建一个,如果是一个已经存在的则表示修改signalfd所关联的信号;
  参数mask:信号集合;
  参数flag:内核版本2.6.27以后支持SFD_NONBLOCK、SFD_CLOEXEC;
  成功返回文件描述符,返回的fd支持以下操作:read、select(poll、epoll)、close
  例子
#include <sys/signalfd.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define handle_error(msg)
do { perror(msg); exit(EXIT_FAILURE); } while (0)
int main(int argc, char *argv[])
{
sigset_t mask;
int sfd;
struct signalfd_siginfo fdsi;
ssize_t s;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGQUIT);
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
handle_error("sigprocmask");
sfd = signalfd(-1, &mask, 0);
if (sfd == -1)
handle_error("signalfd");
for (;;) {
s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
if (s != sizeof(struct signalfd_siginfo))
handle_error("read");
if (fdsi.ssi_signo == SIGINT) {
printf("Got SIGINT ");
} else if (fdsi.ssi_signo == SIGQUIT) {
printf("Got SIGQUIT ");
exit(EXIT_SUCCESS);
} else {
printf("Read unexpected signal ");
}
}
}
  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);
  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 */
}