3

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

4

0 回答 0