首先,为边缘触发阅读的epoll集合添加一个套接字:
epoll_event ev = {};
ev.data.fd = sock;
ev.events = EPOLLIN | EPOLLET; // edge triggered reading
epoll_ctl(efd, EPOLL_CTL_ADD, sock, &ev);
字符串
等待数据:
result = epoll_wait(efd, events, sizeEvents, timeoutMilliseconds);
型
假设有20多个字节的数据可用,但随后的代码希望将流中的消息解析为10个字节的块:
result = recv(sock, buffer, 10, 0);
型
所以此时,您可能会说,“如果他调用epoll_wait
,即使套接字流中还有剩余的10个字节尚未读取,他的代码也可能挂起或超时。”
但是,我的代码实际上并没有返回epoll_wait,而是切换了epoll标志,这样它就可以在同一个套接字上发回响应。
ev.data.fd = sock;
ev.events = EPOLLOUT|EPOLLET;
epoll_ctl(efd, EPOLL_CTL_MOD, sock, &ev);
型
请注意,EPOLLIN不再被设置,然后代码执行send
和epoll_wait
的标准循环,直到发送完整的响应。
设置消息响应后,代码返回边沿触发模式下的阅读:
ev.data.fd = sock;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(efd, EPOLL_CTL_MOD, sock, &ev);
型
然后等待:
result = epoll_wait(efd, events, sizeEvents, timeoutMilliseconds);
型
现在假设自上次读取套接字以来没有额外的数据到达sock
,上面的epoll_wait
是否因为边缘级别没有改变而挂起(或超时)?或者EPOLLIN被关闭并再次打开的事实是否允许边缘状态被重置,以便上面的epoll_wait
调用将立即返回以指示套接字上的可用数据?
1条答案
按热度按时间gjmwrych1#
切换监控事件仍会导致
epoll_wait()
挂起。ET模式下的epoll_wait()
会对一个回调函数做出React,该函数是在根据监控事件对文件描述符进行更改时触发的。您仍然需要等待一些新数据到达该fd
,以便接收epoll_wait()
通知。