Socket epoll:EPOLL_CTL_MOD会重置边沿触发吗?

问题描述 投票:0回答:1

首先将套接字添加到 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 标志,而不是返回 epoll_wait,这样它就可以在同一个套接字上发送响应。

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
调用将立即返回以指示套接字上可用的数据?

linux sockets epoll epollet
1个回答
0
投票

切换受监控的事件仍会导致

epoll_wait()
挂起。 ET 模式下的
epoll_wait()
会对回调函数做出反应,当根据监视的事件对文件描述符进行更改时会触发该回调函数。您仍然需要等待一些新数据到达
fd
才能收到
epoll_wait()
通知。

© www.soinside.com 2019 - 2024. All rights reserved.