я в настоящее время добавления sockfds, созданный из accept к Epoll например со следующими событиями:Epoll с запуском по фронту и OneShot сообщает только один раз
const int EVENTS = (
EPOLLET |
EPOLLIN |
EPOLLRDHUP |
EPOLLONESHOT |
EPOLLERR |
EPOLLHUP);
Когда событие срабатывает, я передаю его в обработчик поток, прочитайте, а затем снова включите sockfd через epoll_ctl
с теми же флагами. Тем не менее, я получаю только событие EPOLLIN
один раз. Кроме того, если я убью клиента в любое время после получения первого события, я тоже не получаю события отвлечения. Из чтения man-страниц, я думал, что понял правильный подход с 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 для чтения событий из отдельного потока?
MCVE поможет много. Например, псевдокод не объясняет взаимосвязи между циклом события и потоками обработчика.Здесь есть три «движущиеся части»: EPOLLET (вы пробовали свой код без этого флага?), EPOLLONESHOT и многопоточность. Таким образом, диагностика проблемы _real_ соответственно затруднена. – arayq2