新的API eventfd、signalfd、timerfd
目前比较新的Linux 内核都支持这三个函数
1、eventfd
#include <sys/eventfd.h>
int eventfd(unsigned int initval, int flags);
eventfd() creates an "eventfd object" that can be used as an event
wait/notify mechanism by user-space applications, and by the kernel
to notify user-space applications of events. The object contains an
unsigned 64-bit integer (uint64_t) counter that is maintained by the
kernel. This counter is initialized with the value specified in the
argument initval.
查看man手册,大概的意思为通过内核通知 user-space的方式进行的,使用一个64-bit来作为值。
flags (1)EFD_CLOEXEC 在出现exec时 主动关闭这个eventfd
flags (2)EFD_NONBLOK 非阻塞
flags (2) EFD_SEMAPHORE
函数返回一个文件描述符(eventfd object)
eventfd 主要用于进程或者线程间通讯(通知、等待机制 nginx中有使用),实现方式为read、write来想eventfd中写入和读取。
2、timerfd
#include <sys/timerfd.h>
int timerfd_create(int clockid, int flags); 返回一个timerfd
int timerfd_settime(int fd, int flags,
const struct itimerspec *new_value,
struct itimerspec *old_value); 设置timer周期
int timerfd_gettime(int fd, struct itimerspec *curr_value); 得到到期时间
结构体对应(来自man)
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 */
};
3、signalfd
#include <sys/signalfd.h> int signalfd(int fd, const sigset_t *mask, int flags);
signalfd是一个在linux kernel 2.6.22提供的系统调用,功能是使用一个fd来接收信号。这样就可以同步地处理信号,也不需要设置处理函数。可以man signa lfd 查看示例程序。首先必须使用sigprocmask来屏蔽要使用signalfd来处理的信号,然后调用signalfd创建一个fd用来读取到达的信号。当被屏蔽的信号到达时,程序将不会被中断,也不会有处理函数被调用。信号会在fd中排队。signalfd创建的fd可以和其他fd一样:可以放在select, poll, epoll中;可以设置为非阻塞;可以为不同的信号创建不同的fd;在fork之后该fd也不会关闭掉,子进程同样可以读懂发送给父进程的信号。signalfd非常适合在主循环中执行epoll处理大量连接的单进程网络服务程序中使用,信号的处理可以和其他fd一样加到epoll中。由于程序不会被中断,可以选择合适的时机才去处理信号
其实上面的三个函数创建的fd 都可以放在epoll中进行监听操作,完成非阻塞的操作,这样可以大大提高程序的处理性能,建议去使用。