概念
eventfd是Linux2.6提供的系统调用,可以用来实现事件通知。
eventfd是一个由内核维护的64位无符号整型(uint64_t)计数器,创建eventfd返回一个文件描述符,进程间通过对这个文件描述符read/write读取/改变计数器的值,实现进程间通信。
详细用法可以通过 man eventfd
查看
函数原型
#include<sys eventfd.h="">
int eventfd(unsigned int initval, int flags);
/*
函数功能:创建eventfd
返回值:文件描述符fd
initval:信号量初始值
flags:设置标志位(2.6.27以上内核有效,2.6.26或之前版本的内核,flags值为0)
* EFD_NONBLOCK 设置返回的eventfd非阻塞
* EFD_CLOEXEC 示返回的eventfd文件描述符在fork后exec其他程序时会自动关闭这个文件描述符
* EFD_SEMAPHORE表示将eventfd作为一个**信号量**来使用
*/
API
int eventfd(unsigned int initval, int flags);//创建一个eventfd文件描述符
int eventfd_read(int fd, eventfd_t *value); //从eventfd中读取一个值
int eventfd_write(int fd, eventfd_t value); //向eventfd写入一个值
eventfd_read()
read(2)
Each successful read(2) returns an 8-byte integer. A read(2) fails with the error EINVAL if the size of the supplied buffer is less than 8 bytes.
The value returned by read(2) is in host byte order—that is, the native byte order for integers on the host machine.
The semantics of read(2) depend on whether the eventfd counter currently has a nonzero value and whether the EFD_SEMAPHORE flag was specified when creating the eventfd file descriptor:
* If EFD_SEMAPHORE was not specified and the eventfd counter has a nonzero value, then a read(2) returns 8 bytes containing that value, and the counter‘s value is reset to zero.
* If EFD_SEMAPHORE was specified and the eventfd counter has a nonzero value, then a read(2) returns 8 bytes containing the value 1, and the counter‘s value is decremented by 1.
* If the eventfd counter is zero at the time of the call to read(2), then the call either blocks until the counter becomes nonzero (at which time, the read(2) proceeds as described
above) or fails with the error EAGAIN if the file descriptor has been made nonblocking.
- 读取返回一个8byte的整数
- 如果提供的缓冲区的大小小于8个字节返回错误EINVAL
- 如果eventfd设置了EFD_SEMAPHORE,那么每次read就会返回1,并且让eventfd对应的计数器减一;如果eventfd没有设置EFD_SEMAPHORE,那么每次read就会直接返回计数器中的数值,read之后计数器就会置0。不管是哪一种,当计数器为0时,如果继续read,那么read就会阻塞(如果eventfd没有设置EFD_NONBLOCK)或者返回EAGAIN错误(如果eventfd设置了EFD_NONBLOCK)。
eventfd_write()
write(2)
A write(2) call adds the 8-byte integer value supplied in its buffer to the counter. The maximum value that may be stored in the counter is the largest unsigned 64-bit value minus 1
(i.e., 0xfffffffffffffffe). If the addition would cause the counter‘s value to exceed the maximum, then the write(2) either blocks until a read(2) is performed on the file descriptor,
or fails with the error EAGAIN if the file descriptor has been made nonblocking.
A write(2) fails with the error EINVAL if the size of the supplied buffer is less than 8 bytes, or if an attempt is made to write the value 0xffffffffffffffff.
- 写入调用将缓冲区中提供的8字节整数值添加到计数器。计数器中可以存储的最大值是最大的无符号64位值减去1(即0xFFFFFFFFFFFE)。如果加法会导致计数器的值超过最大值,则write会阻塞,直到对文件描述符执行read,如果文件描述符已被设置为非阻塞,则失败并返回错误EAGAIN。
- 如果提供的缓冲区大小小于8字节,或者尝试写入值0xFFFFFFFFFFFFFF,则write失败,并出现错误EINVAL。
refs
https://www.cnblogs.com/ck1020/p/7214310.html
https://blog.csdn.net/qq_28114615/article/details/97929524
https://www.cnblogs.com/zhengchunhao/p/5335914.html