事件通知Event notification
条件满足时通知等待方处理工作,把唤醒信号与实际数据、状态的存储分开。
- 核心约束
- 通知与工作状态的发布、消费必须遵守同一同步协议;收到通知后仍应检查实际队列或状态。
- 适用问题
- 设备队列通知、事件循环、线程间唤醒,以及内核与用户态协作。
- 边界与取舍
- eventfd 累积的是 64 位计数而非任意消息载荷;普通读取会取出当前计数并清零,EFD_SEMAPHORE 则每次减一。多次信号不等于逐条保存业务事件,数据可见性和资源生命周期仍需另行保证。
常见操作#
w 为本次实际唤醒的等待者数量;以 eventfd / ioeventfd 为例。
| 操作 | 时间成本 | 条件与说明 |
|---|---|---|
| 更新通知状态 | 计数更新 + 同步操作 | eventfd 使用 64 位计数器;计数聚合不等于为每个事件保存独立记录。 |
| 检查并唤醒等待者 | 与等待队列及唤醒数量有关 | 唤醒后还要等待调度;API 不保证每次 write 都对应一次独立执行。 |
| 批量消费通知 | 读取计数 + 处理实际工作队列 | 计数仅代表通知状态,真正工作仍需从共享队列等位置读取。 |
时间与空间#
- 时间成本
- 条件匹配、计数同步、唤醒与工作处理分别计费
- 空间成本
- 通知对象 + 等待队列 + 应用自身工作队列
KVM ioeventfd 可减少设备通知进入 QEMU 模拟路径的次数,但不会消除所有 VM exit 或所有数据处理。
工程中的应用#
2 个案例 · 附源码KVM 预先匹配设备通知地址,命中后 signal eventfd,使通知无需让 vCPU 逐次退回 QEMU 分派。
附源码片段 · 并发与一致性
libvirt 把 FD 和定时器接到 GLib 主循环,将停止监听与释放对象分开,并提高连接清理任务的优先级,避免资源用尽时清理一直排不上。
附源码片段 · 并发与一致性
基础原理参考资料
Linux man-pages · eventfd(2)计数器、阻塞、EFD_SEMAPHORE 及可轮询通知语义。
Linux 6.12 · eventfd.c通知计数、EFD_SEMAPHORE 读语义、等待队列和溢出检查的实际代码。
Linux 6.12 · KVM_IOEVENTFD地址匹配与向 eventfd 发送通知的 KVM 接口。