eventfd 在内核版本,2.6.22以后有效。查看内核版本可以用命令 uname -r
在看muduo源码时,项目中使用eventfd机制实现线程间的唤醒(通知)。觉得效率比较高,所以拿来学习下。其也可以实现父子进程间的通信。
首先使用: man eventfd
name:eventfd–创建一个用于事件通知的描述符
SYNOPSIS:
#include<sys/eventfd.h>
int eventfd(unsigned int initval,int flags);
DESCRIPTION:
eventfd是用于创建一个“eventfd object”,它可以用于用户态-用户态和内核态-用户态之间实现事件通知的机制,这个object包括一个64位计数器(initval,内核维护)。
flags–可以改变eventfd的行为,
EFD_CLOEXEC(从linux 2.6.27开始支持)–类似于close-on-exec(FD_CLOEXEC)在open函数的作用,即这个句柄我在fork子进程后执行exec时就关闭。
EFD_NONBLOCK(从linux 2.6.27开始支持)–当使用eventfd创建一个新的描述符设置了该状态时,将该描述符设为非阻塞状态。
EFD_SEMAPHORE(从linux 2.6.30开始支持)–对于read该文件描述符是提供类似信号的语义,具体含义如下会介绍。
return values 返回值:eventfd()返回一个新的文件描述符(efd)可以用于引用eventfd对象,可以对efd执行以下操作:
read(2):如果读成功,则返回一个8-byte的整数,如果读入的数小于8-byte,则会导致读错误,并设置error 为EIVAL。返回的整数是主机序的。read(2)返回值的语义是由当前的initval非零和是否设置EFD_SEMAPHORE flag决定的。
* 如果EFD_SEMAPHORE flag没有被设置,并且eventfd 的counter是一个非零值,则read(2)会返回该counter 的数值,并且将该counter置零。
* 如果设置了EFD_SEMAPHORE flag并且counter的值是非零的,则read(2)会返回一个8-byte 的为1的整数,并且将counter的值减1.
* 如果在read(2)的时候,counter的值为0,则将会阻塞直到counter大于0,如果设置为 EFD_NONBLOCK,则会立刻返回,并将error设置为EAGAIN。
write(2):改操作会将当前的一个8-byte的数字累加到counter的缓存中,counter的最大值为2^64-1。如果write导致counter值超过最大值,则会阻塞直到对该描述符执行read(2),否则会导致写失败,返回错误 EAGAIN。如果写入的数值字节小于8-byte,则会返回错误,EINVAL。
poll(2),select(2),epoll(2)都可以监听该描述符。
close(2) – 当这个文件描述符不需要的时候,我们需要关闭它。当所有的关联的文件描述符都被关闭时,内核中的eventfd对象才会被释放。<