我正在添加从接受创build的sockfds到一个epoll实例有下列事件:
const int EVENTS = ( EPOLLET | EPOLLIN | EPOLLRDHUP | EPOLLOnesHOT | EPOLLERR | EPOLLHUP);
一旦事件被触发,我将它传递给一个处理程序线程,读取,然后通过使用相同标志的epoll_ctl重新启用sockfd。 不过,我只收到一次EPOLLIN事件。 另外,如果我在第一个事件收到后随时杀死客户端,我也不会挂断事件。 从阅读手册页,我认为我了解EdgeTriggered和Oneshot的正确方法。
以下是我正在使用的过程的一些伪代码:
const int EVENTS = ( EPOLLET | EPOLLIN | EPOLLRDHUP | EPOLLOnesHOT | EPOLLERR | EPOLLHUP); void event_loop() { struct epoll_event event; struct epoll_event *events; events = calloc(100,sizeof event); while (1) { int x; int num_events = epoll_wait(epfd,events,100,-1); for (x = 0; x < num_events; x++) { another_thread(fd); } } } void another_thread(int fd) { // Read stuff until EAGAIN struct epoll_event event; event.data.fd = fd; event.events = EVENTS; epoll_ctl(epfd,EPOLL_CTL_MOD,fd,&event); }
当我执行EPOLL_CTL_MOD操作时,我没有收到任何错误,但从来没有得到其他事件的通知。 如果我在第一个事件之后重复读取循环,它将读取客户端发送的所有后续数据,所以我知道数据正在进入,并且fd仍处于打开状态并正在工作。
在c ++中使用shell命令
如何在C / C ++中以编程方式读取Linux文件权限
错误:无法调用'min(long unsigned int&,unsigned int&)'的匹配函数
在windows 7和msvc下编译QT 5.3.2
从检查strace ,线程是从克隆创build的,并具有标志CLONE_FILES ,所以所有的线程共享相同的CLONE_FILES表。
在Ubuntu上的虚拟机上学习Linux内核编程?
c ++在后台运行system(),在dirpath中input空格,输出到文本文件
GDB和核心转储问题
LD_PRELOAD哪个程序是目标
忽略系统调用
不过,我只收到一次EPOLLIN事件。 另外,如果我在第一个事件收到后随时杀死客户端,我也不会挂断事件。
epoll_ctl(2)的手册页说:
EPOLLOnesHOT(自Linux 2.6.2开始)设置关联文件描述符的一次性行为。 这意味着在事件被epoll_wait(2)拉出之后,关联的文件描述符被内部禁用,epoll接口不会报告其他事件。 用户必须使用EPOLL_CTL_MOD调用epoll_ctl()以使用新的事件掩码重新装入文件描述符。
在你的情况下,当你得到第一个事件,epoll禁用你的sockfd。 当您使用EPOLL_CTL_MOD重新启用EPOLL_CTL_MOD ,它将在重新注册后通知内核收到的所有事件。 因此,第一次通知和重新注册之间的任何事件都将丢失。 这可能是没有得到任何挂断事件或数据的原因。
从事件中删除EPOLLOnesHOT将更正您的代码,最终不需要重新启用sockfd。
而且由于您使用EPOLLET ,所以也不会有任何性能问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。