Linux 插座epoll:epoll\U CTL\U MOD是否会重置边缘触发器?
首先,将套接字添加到epoll集合以进行边缘触发读取: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_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。