You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

触发EPOLLONESHOT事件后关闭Socket,是否需手动调用EPOLL_CTL_DEL?

EPOLLONESHOT触发后,关闭Socket前需要调用EPOLL_CTL_DEL吗?

答案是必须调用,原因如下:

  • 事件禁用和从epoll实例移除是两码事
    EPOLLONESHOT的作用只是让该Socket的事件触发一次后暂停通知,但Socket仍然和epoll实例保持关联,内核会维护对应的关联数据。而EPOLL_CTL_DEL是彻底将Socket从epoll的监控列表中移除,释放内核中对应的关联资源。

  • 避免资源泄漏
    有些内核版本不会在Socket关闭时自动清理epoll中的关联条目,如果长期不调用EPOLL_CTL_DEL,会导致内核资源占用累积。不要依赖内核的“自动清理”行为,这并非标准规定,不同系统的实现存在差异。

  • 调用EPOLL_CTL_DEL不会报错
    只要Socket和epfd处于有效状态,即便事件已经被禁用,调用epoll_ctl(epfd, EPOLL_CTL_DEL, some_socket, NULL)也是安全的,不会返回错误。如果Socket已经关闭,调用可能会返回EBADF,但此时Socket本身已无效,不会造成资源泄漏,忽略该错误即可。

附上你的代码示例:

struct epoll_event ev, events[20];
ev.events = EPOLLOUT | EPOLLONESHOT;
ev.data.sock = some_socket;
epoll_ctl(epfd, EPOLL_CTL_ADD, some_socket, &ev);
// then the EPOLLOUT event has triggered by epoll_wait
epoll_ctl(epfd, EPOLL_CTL_DEL, some_socket, NULL); // should it be called? will it cause error?

内容的提问来源于stack exchange,提问作者benrush

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 20:22:15