惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Cisco Blogs
爱范儿
爱范儿
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
Jina AI
Jina AI
Project Zero
Project Zero
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
Simon Willison's Weblog
Simon Willison's Weblog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tenable Blog
F
Fortinet All Blogs
大猫的无限游戏
大猫的无限游戏
Last Week in AI
Last Week in AI
月光博客
月光博客
雷峰网
雷峰网
G
Google Developers Blog
V
V2EX
T
Tor Project blog
罗磊的独立博客
Schneier on Security
Schneier on Security
Know Your Adversary
Know Your Adversary
W
WeLiveSecurity
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
P
Privacy International News Feed
S
Securelist
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
P
Proofpoint News Feed
Blog — PlanetScale
Blog — PlanetScale
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
小众软件
小众软件
Scott Helme
Scott Helme
I
Intezer
T
Threat Research - Cisco Blogs
The GitHub Blog
The GitHub Blog
N
Netflix TechBlog - Medium
C
CERT Recently Published Vulnerability Notes
Security Archives - TechRepublic
Security Archives - TechRepublic
酷 壳 – CoolShell
酷 壳 – CoolShell
L
LINUX DO - 最新话题
N
News | PayPal Newsroom
L
Lohrmann on Cybersecurity
T
Troy Hunt's Blog
Google DeepMind News
Google DeepMind News
P
Proofpoint News Feed
人人都是产品经理
人人都是产品经理
Latest news
Latest news
AWS News Blog
AWS News Blog
Apple Machine Learning Research
Apple Machine Learning Research

博客园 - 蓝天上的云℡

事件驱动编程模式之EventLoop syslog日志查看器GUI图形界面,支持Windows/Linux/Macos开箱即用 ERRNO链条分析 ARM AMBA总线之AXI系 Linux Kernel Init Bootstrap 内核初始化启动 RK芯片平台GPIO控制 Linux USB子系统之Gadget设备端驱动 远程调试桥接-网络-ADB-GDB 斐讯N1盒子安装飞牛FNOS NAS 安卓以太网链路检测 安卓原生开发-Recovery使用minui绘制图形 蓝牙音频协议——安卓开发 RKxx系列的RK628摄像头配置影响HDMI出图 usb储存之BOT/UAS内核驱动 现代操作系统-音频处理技术1 Linux驱动底层 Linux驱动适配I2C/SPI例子 模块编译的pr_debug Linux内核/GKI内核主线更新-usb网卡名称变更引出的BUG 为Kernel代码生成VSCODE索引,快速跳转 安卓开机时间/性能优化 Linux/Golang/glibC系统调用 SGDMA与普通DMA Linux内核源码-存储驱动之 QSPI Flash golang数据转换技巧
事件编程之eventfd
蓝天上的云℡ · 2026-05-07 · via 博客园 - 蓝天上的云℡

介绍

eventfd是一个内核实现的线程间/进程间通讯的事件通知机制

man

https://man7.org/linux/man-pages/man2/eventfd.2.html

int eventfd(unsigned int initval, int flags);
支持read/write/poll/select

       EFD_CLOEXEC (since Linux 2.6.27)
              Set the close-on-exec (FD_CLOEXEC) flag on the new file
              descriptor.  See the description of the O_CLOEXEC flag in
              open(2) for reasons why this may be useful.

       EFD_NONBLOCK (since Linux 2.6.27)
              Set the O_NONBLOCK file status flag on the open file
              description (see open(2)) referred to by the new file
              descriptor.  Using this flag saves extra calls to fcntl(2)
              to achieve the same result.

       EFD_SEMAPHORE (since Linux 2.6.30)
              Provide semaphore-like semantics for reads from the new
              file descriptor.  See below.

exam

           $ ./a.out 1 2 4 7 14
           Child writing 1 to efd
           Child writing 2 to efd
           Child writing 4 to efd
           Child writing 7 to efd
           Child writing 14 to efd
           Child completed write loop
           Parent about to read
           Parent read 28 (0x1c) from efd
       #include <err.h>
       #include <inttypes.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/eventfd.h>
       #include <sys/types.h>
       #include <unistd.h>

       int
       main(int argc, char *argv[])
       {
           int       efd;
           uint64_t  u;
           ssize_t   s;

           if (argc < 2) {
               fprintf(stderr, "Usage: %s <num>...\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           efd = eventfd(0, 0);
           if (efd == -1)
               err(EXIT_FAILURE, "eventfd");

           switch (fork()) {
           case 0:
               for (size_t j = 1; j < argc; j++) {
                   printf("Child writing %s to efd\n", argv[j]);
                   u = strtoull(argv[j], NULL, 0);
                           /* strtoull() allows various bases */
                   s = write(efd, &u, sizeof(uint64_t));
                   if (s != sizeof(uint64_t))
                       err(EXIT_FAILURE, "write");
               }
               printf("Child completed write loop\n");

               exit(EXIT_SUCCESS);

           default:
               sleep(2);

               printf("Parent about to read\n");
               s = read(efd, &u, sizeof(uint64_t));
               if (s != sizeof(uint64_t))
                   err(EXIT_FAILURE, "read");
               printf("Parent read %"PRIu64" (%#"PRIx64") from efd\n", u, u);
               exit(EXIT_SUCCESS);

           case -1:
               err(EXIT_FAILURE, "fork");
           }
       }

使用

创建eventfd并获取一个fd描述符
线程A:对fd写入值
线程B:对fd读取值

读写的过程是read/write堵塞操作,会有调度。

原理

系统调用 eventfd2
通过select/poll等io多路并发检测,通过read/write这种堵塞调度来实现事件的等待和执行。

内核源码:fs/eventfd.c
创建
image
操作
image

比较简单,就是基于等待队列的实现,而且也只能存val,不能存别的东西。
本质上是系统提供的一种简单通讯机制。

应用场景

高性能编程
不同线程间的同步等待可以用eventfd来简洁实现