gpt4 book ai didi

c - 边缘触发的 Epoll 和 oneshot 只报告一次

转载 作者:IT王子 更新时间:2023-10-29 00:44:19 29 4
gpt4 key购买 nike

我目前正在添加从 accept 创建的 sockfds到具有以下事件的 epoll 实例:

const int EVENTS = (
EPOLLET |
EPOLLIN |
EPOLLRDHUP |
EPOLLONESHOT |
EPOLLERR |
EPOLLHUP);

一旦事件被触发,我将其传递给处理程序线程,读取并通过具有相同标志的 epoll_ctl 重新启用 sockfd。但是,我只收到一次 EPOLLIN 事件。此外,如果我在收到第一个事件后随时终止客户端,我也不会收到挂断事件。通过阅读手册页,我认为我理解了使用 EdgeTriggered 和 OneShot 的正确方法。

下面是我正在使用的过程的一些伪代码:

const int EVENTS = (
EPOLLET |
EPOLLIN |
EPOLLRDHUP |
EPOLLONESHOT |
EPOLLERR |
EPOLLHUP);

void event_loop()
{
struct epoll_event event;
struct epoll_event *events;
events = calloc(100, sizeof event);
while (1)
{
int x;
int num_events = epoll_wait(epfd, events, 100, -1);
for (x = 0; x < num_events; x++)
{
another_thread(fd);
}
}
}

void another_thread(int fd)
{
// Read stuff until EAGAIN

struct epoll_event event;
event.data.fd = fd;
event.events = EVENTS;
epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &event);
}

当我执行 EPOLL_CTL_MOD 操作时,我没有收到任何错误,但从未收到其他事件的通知。如果我在第一个事件后让读取循环保持重复,它将读取客户端发送的所有后续数据,所以我知道数据正在进入并且 fd 仍然打开并工作。

通过检查 strace,线程是从 clone 创建的并具有标志 CLONE_FILES,因此所有线程共享同一个 fd 表。

为来自单独线程的读取事件重新启用 fd 的正确方法是什么?

最佳答案

However, I only receive the EPOLLIN event one time. Also, if I kill the client anytime after the first event is received, I do not get hangup events either.

epoll_ctl(2) 的手册页说:

EPOLLONESHOT (since Linux 2.6.2) Sets the one-shot behavior for the associated file descriptor. This means that after an event is pulled out with epoll_wait(2) the associated file descriptor is internally disabled and no other events will be reported by the epoll interface. The user must call epoll_ctl() with EPOLL_CTL_MOD to rearm the file descriptor with a new event mask.

在您的情况下,当您获得第一个事件时,epoll 会禁用您的 sockfd。当您使用 EPOLL_CTL_MOD 重新启用您的 sockfd 时,它会通知内核在重新注册后 收到的所有事件。因此,第一次通知和重新注册之间的任何事件都将丢失。这可能是没有获得任何挂断事件或数据的原因。

从事件中删除 EPOLLONESHOT 将更正您的代码,最终您也不需要重新启用 sockfd。

而且由于您使用的是 EPOLLET,因此也不会有任何性能问题。

关于c - 边缘触发的 Epoll 和 oneshot 只报告一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33885439/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com