资讯动态

EPOLLET(边缘触发)+ 非阻塞读:为什么会遇到 “Resource temporarily unavailable”,以及正确写法(含完整代码与运行结果)

发布时间:2026/8/4 3:55:43 来源:尧图企业网站定制
1. 现象复现:非阻塞循环读取时的 “Resource temporarily unavailable”当你把 socket 设置为非阻塞后,再在某个循环里不断recv():数据还没到:不会卡住(不阻塞)而是立即返回-1并把errno置为EAGAIN或EWOULDBLOCKperror()打印常见为:Resource temporarily unavailable这不是“真的出错”,而是内核告诉你:现在读缓冲区空了,别读了。2.recv/read返回值速查表(考试/面试高频)返回值含义常见场景你该怎么做0成功读取 N 字节缓冲区有数据继续处理/继续读(ET 下通常继续读)=0对端关闭连接(FIN)客户端正常断开epoll_ctl DEL+close(fd)=-1且errno=EAGAIN/EWOULDBLOCK非阻塞下“读空了”缓冲区暂时没数据停止本轮读取,回到 epoll 等下一次事件=-1且其他 errno真错误如ECONNRESET打印错误并清理连接便携写法:同时判断EAGAIN和EWOULDBLOCK(很多系统它俩值相同,但别赌)。3. 正确设置非阻塞:fcntl三步走#includefcntl.hintset_nonblock(intfd){intflags=fcntl(fd,F_GETFL,0);if(flags==-1)return-1;if(fcntl(fd,F_SETFL,flags|O_NONBLOCK)==-1)return-1;return0;}4. 为什么 EPOLLET 必须“读到 EAGAIN”为止?**边缘触发(EPOLLET)**的核心特性:从“无数据” → “有数据”的那一下,只通知一次如果你没有把缓冲区读空,后续数据可能仍在缓冲区里,但不会再触发事件所以 ET 模式下标准范式是:循环读→ 读到EAGAIN/EWOULDBLOCK(表示本次读空)→ 才结束下面这张流程图是 ET 下读事件处理的标准写法:

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价