Linux eventfd

eventfd

Linux 2.6.27后添加的新特性,eventfd。

eventfd是一个由内核维护的64位无符号整型(uint64_t)计数器,创建eventfd返回一个文件描述符,进程间通过对这个文件描述符read/write读取/改变计数器的值,实现进程间通信。
eventfd的创建是通过eventfd函数实现的,返回值即是该eventfd所对应的文件描述符
函数原型:int eventfd(unsigned int initval, int flags); 在头文件sys/eventfd.h中

initval:创建eventfd时它所对应的64位计数器的初始值

  • EFD_CLOEXEC (since Linux 2.6.27):
    文件被设置成 O_CLOEXEC,创建子进程 (fork) 时不继承父进程的文件描述符。
  • FD_CLOEXEC 标志,即 close-on-exec,这样在调用 exec 后会自动关闭文件描述符。因为通常执行另一个程序后,会用全新的程序替换子进程的正文,数据,堆和栈等,原来的文件描述符变量也不存在了,这样就没法关闭没用的文件描述符了。
  • EFD_NONBLOCK(since Linux 2.6.27):
    设置文件描述符为非阻塞的
    设置了这个标志后,如果没有数据可读,就返回一个 EAGAIN 错误,不会一直阻塞。
  • EFD_SEMAPHORE (since Linux 2.6.30):
    提供类似信号量语义的 read 操作,简单说就是计数值 count 递减 1。可以多次read

eventfd_read():

  1. 读取返回一个8byte的整数
  2. 如果提供的缓冲区的大小小于8个字节返回错误EINVAL
  3. 如果eventfd设置了EFD_SEMAPHORE,那么每次read就会返回1,并且让eventfd对应的计数器减一;如果eventfd没有设置EFD_SEMAPHORE,那么每次read就会直接返回计数器中的数值,read之后计数器就会置0。不管是哪一种,当计数器为0时,如果继续read,那么read就会阻塞(如果eventfd没有设置EFD_NONBLOCK)或者返回EAGAIN错误(如果eventfd设置了EFD_NONBLOCK)。

eventfd_write():

  1. 写入调用将缓冲区中提供的8字节整数值添加到计数器。计数器中可以存储的最大值是最大的无符号64位值减去1(即0xFFFFFFFFFFFE)。如果加法会导致计数器的值超过最大值,则write会阻塞,直到对文件描述符执行read,如果文件描述符已被设置为非阻塞(EFD_NONBLOCK),则失败并返回错误EAGAIN。
  2. 如果提供的缓冲区大小小于8字节,或者尝试写入值0xFFFFFFFFFFFFFF,则write失败,并出现错误EINVAL。

参考:https://blog.csdn.net/zhizhengguan/article/details/111212174

posted @ 2022-09-15 21:34  227569hy  阅读(197)  评论(0)    收藏  举报