eventfd、timerfd_create使用

eventfd()使用场景

在 pipe 仅用于发出事件信号的所有情况下,都可以使用 eventfd 取而代之。

example

int createEventfd()
{
  int evtfd = ::eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
  if (evtfd < 0)
  {
    LOG_SYSERR << "Failed in eventfd";
    abort();
  }
  return evtfd;
}

EFD_NONBLOCK 表示创建的文件描述符非阻塞,read和write都不会阻塞;
EFD_CLOEXEC表示在执行fork或者exec后都不会继承父进程的打开状态;

操作方式

操作方法
一切皆为文件是 Linux 内核设计的一种高度抽象,eventfd 的实现也不例外,我们可以使用操作文件的方法操作 eventfd。

read(): 读取 count 值后置 0。如果设置 EFD_SEMAPHORE,读到的值为 1,同时 count 值递减 1。
write(): 其实是执行 add 操作,累加 count 值。
epoll()/poll()/select(): 支持 IO 多路复用操作。
close(): 关闭文件描述符,eventfd 对象引用计数减 1,若减为 0,则释放 eventfd 对象资源。

timerfd_create()使用场景

timerfd是Linux为用户程序提供的一个定时器接口。这个接口基于文件描述符,通过文件描述符的可读事件进行超时通知,所以能够被用于select/poll的应用场景。

使用

#include 

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);
int createTimerfd()
{
  // 创建一个 时间 fd
  int timerfd = ::timerfd_create(CLOCK_MONOTONIC,
                                 TFD_NONBLOCK | TFD_CLOEXEC);
  if (timerfd < 0)
  {
    LOG_SYSFATAL << "Failed in timerfd_create";
  }
  return timerfd;
}

TFD_NONBLOCK 表示非阻塞的文件描述符
TFD_CLOEXEC 表示fork或者exec后自动关闭,不会继承父进程的打开状态
CLOCK_MONOTONIC 是单调时间,即从某个时间点开始到现在过去的时间,用户不能修改这个时间

你可能感兴趣的:(C++,eventfd,线程通信)