如何将select实现的可写/异常事件监听逻辑移植为poll
select转poll实现方案
你当前写的poll基础框架有个初始配置错误:POLLIN是监听可读事件的标志,和你原代码监听可写、异常事件的逻辑不符,需要先修正事件注册项。
事件对应规则
原select逻辑的两类触发事件和poll的标志位对应关系很直接:
- 可写事件:原select通过writefds集合监听,对应poll的
POLLOUT标志,需要主动配置到pollfd.events字段 - 异常事件:原select通过exceptfds集合监听,对应poll的错误类返回标志,包含
POLLERR(IO错误)、POLLHUP(链路挂起)、POLLNVAL(文件描述符非法),这类事件不需要主动注册,poll检测到fd异常时会自动在返回结果里置位
触发判断方法
poll返回后,内核会把实际触发的事件写入对应pollfd结构的revents字段,你只需要用位与操作检查对应标志位是否存在即可,逻辑和原代码里FD_ISSET的判断完全对齐。
完整可运行代码
struct pollfd pollfds[1]; pollfds[0].fd = cameraUSBP.fd; // 仅需注册需要主动监听的可写事件,错误事件由内核默认上报 pollfds[0].events = POLLOUT; while (1) { int res = poll(pollfds, 1, -1); // 建议补充poll调用本身的错误处理,比如被信号中断时直接重试 if (res < 0) { continue; } // 检测到异常事件,调用对应处理函数 if (pollfds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) { errorData(); } // 检测到可写事件,调用对应处理函数 if (pollfds[0].revents & POLLOUT) { writeData(); } }
补充说明:select每次调用都会修改传入的fd_set,所以循环里每次调select前都要重新初始化fd集合;但poll不会修改
events字段,只会更新revents字段,不需要每次循环重复配置pollfd,使用上比select更简便。
内容的提问来源于stack exchange,提问作者gregoiregentil
相关产品推荐
相关产品推荐

