提问人:Simon Walke 提问时间:8/9/2023 最后编辑:Simon Walke 更新时间:8/10/2023 访问量:66
如何重置使用 EFD_SEMAPHORE 创建的 Linux 事件描述符
How to reset a Linux event descriptor created with EFD_SEMAPHORE
问:
我有一个用 C 代码创建的事件描述符,如下所示:
int notifyED = eventfd(0, EFD_SEMAPHORE | EFD_CLOEXEC);
计数器按预期上升和下降,这是调用 和 的结果。eventfd_read()
eventfd_write()
到目前为止一切都很好。现在,我想“刷新”此事件 FD 中的 64 位计数器,以便它重置为零。
刷新操作需要对监视事件 FD 的任何轮询/电子轮询实例“透明”。
刷新后,任何轮询实例都不应生成新的 POLIN,直到进一步发生。
eventfd_write()
显然,类似信号量的语义会阻止计数器在单个 read() 操作中被重置,所以我以这种方式实现了刷新:
int flushED = eventfd(0, EFD_SEMAPHORE);
notifyED = dup3(flushED, notifyED, O_CLOEXEC);
close(flushED);
如果我正确理解了文档页面及其变体,则应以原子方式关闭并重新分配事件描述符。注意:程序总是在退出之前显式调用。dup()
dup3()
close(notifyED)
编辑:更新为用于维护 CLOEXEC 标志,并在有关关闭两个描述符的注释中加入反馈。dup3()
我已经知道的替代解决方案:
具体到 epoll,请使用 ctl_add() 和 ctl_del() 将描述符替换为新描述符;
重复调用,直到计数器为零。
eventfd_read()
具体问题:
这种方法可以接受吗?
dup3()
我是否泄露了描述符资源?
根据我的测试,epoll 实例似乎按预期运行。我错过了什么陷阱?
答: 暂无答案
评论
dup2()