Linux 插座epoll:epoll\U CTL\U MOD是否会重置边缘触发器?

Linux 插座epoll:epoll\U CTL\U MOD是否会重置边缘触发器?,linux,sockets,epoll,epollet,Linux,Sockets,Epoll,Epollet,首先,将套接字添加到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);

首先,将套接字添加到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\u wait
,他的代码可能会挂起或超时,即使套接字流中剩余的10个字节尚未读取。”您是正确的

但是我的代码并没有返回到epoll_wait,而是切换了epoll标志,这样它就可以在同一个套接字上发送响应

ev.data.fd = sock;
ev.events = EPOLLOUT|EPOLLET;
epoll_ctl(efd, EPOLL_CTL_MOD, sock, &ev);
请注意,不再设置EPOLLIN。然后代码执行标准循环
send
epoll\u 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\u wait
是否因为边缘级别没有改变而挂起(或超时)?或者,EPOLLIN被关闭和再次打开的事实是否允许重置边缘状态,以便上述
epoll\u wait
调用将立即返回以指示套接字上可用的数据?

使用EPOLLET的全部意义在于,您根本不需要使用epoll\u CTL\u MOD。