eventfd api (linux version >= 2.6.22):
#include <sys/eventfd.h>
int eventfd(unsigned int initval, int flags);
描述:
eventfd() 创建一个“eventfd 对象”,它可以被用户空间应用程序用作事件等待/通知机制,并被内核用来通知用户空间应用程序事件。 该对象包含一个由内核维护的无符号 64 位整数 (uint64_t) 计数器。 该计数器使用参数 initval 中指定的值进行初始化。
参数:
initval: 初始化由内核维护的 uinit64_t 类型值 counter
flags:
EFD_CLOEXEC(Linux version >= 2.6.27):在返回的 fd 上设置 close-on-exec (FD_CLOEXEC) 标志, fork 函数会拷贝一个 fd 并关联到相同的 eventfd 对象,如果没设置此标志则执行execve 等函数子进程默认会持有 fd资源 。
EFD_NONBLOCK(Linux version >= 2.6.27):在返回的 fd 上设置 O_NONBLOCK(非阻塞模式api) 标志
EFD_SEMAPHORE(Linux version >= 2.6.30):使用 read 时见使用指南
Linux version <= 2.6.26 时,flags 必须设置为 0
返回值:
成功返回一个新的 fd。
错误返回 -1,具体错误通过 errno/strerror(errno) 获取
fd 使用指南:
read:
若 buffer 大小低于 8 个字节则返回错误 EINVAL。
若内核 couter != 0 则返回一个 8 字节大小的数值 。
若 flags 未设置 EFD_SEMAPHORE, read 读取返回内核 counter值, 并设置内核 couter = 0
若设置 EFD_SEMAPHORE,read 读取返回 1,并使设置内核couter = couter - 1
若内核 couter == 0:
若 flags 未设置 EFD_NONBLOCK 标志则阻塞调用直到内核 couter != 0 根据上述 couter != 0的情况返回。
若 flags 设置 EFD_NONBLOCK 标志则返回 EAGAIN。
write:
写入 8 个字节大小的数值(范围:0-0xfffffffffffffffe
若内核 couter 超过 0xfffffffffffffffe
若 flags 未设置 EFD_NONBLOCK 标志则阻塞调用直到 read 调用。
若 flags 设置 EFD_NONBLOCK 标志则返回 EAGAIN。
poll/select/epoll
fd 内核支持 I/O 事件模型,如果
如果检测到内核 couter 值溢出,则 select 将唤醒标志 可读和可写 事件,并且 poll(2) 返回 POLLERR 事件。 如上所述,write(2) 永远不会溢出计数器。 但是,如果 KAIO 子系统执行了 2^64 个 eventfd“信号发布”,则可能会发生溢出(理论上可能,但实际上不太可能)。 如果发生溢出,则 read(2) 将返回最大 uint64_t 值(即 0xffffffffffffffff)。
close
关闭文件