Обработка памяти с помощью события struct epoll

Я разрабатываю сервер на C с библиотека epoll и у меня есть вопрос о том, как обрабатывается память для struct epoll_event. Я заметил в некоторых онлайн-примерах, что при создании epoll_ctl звонков events аргумент выделяется в стеке, а затем передается указатель, например:

struct epoll_event ev;
ev.events = EPOLLIN;
epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);

теперь мы все знаем, что происходит с ev когда функция возвращает. Мой вопрос: делает ли библиотека epoll копии этих значений внутренне или она полагается на структура, которую вы передали, чтобы быть выделенной кучей? Будет ли приведенный выше пример полностью нарушить мою реализацию реактора? Если да, то каков наилучший способ отслеживания моей кучи, выделенной epoll_event структуры?

Спасибо за ваше время.

3 ответов


все нормально. The epoll_ctl функция-это простая оболочка вокруг системного вызова, которая будет полностью завершена, когда функция вернется. Никаких дополнительных данных из userspace не требуется. Структура-это просто способ упаковки аргументов.


абсолютно нормально сразу выбросить или повторно использовать структуру epoll_event.

ядро копирует параметры из структуры struct epoll_event.

Это точно так же, как если бы вы использовали ioctl, который принимает структуру в качестве параметра, или операцию сокета (например, bind), которая принимает структуру sockaddr_in.

ядра берет то, что ему нужно, и он сразу же нормально для вас, чтобы освободить его.

единственное, о чем вам нужно беспокоиться, это "пользовательские данные", которые имеют отношение только к вам. Ядро будет хранить его, но вам нужно знать, что это значит, когда вы получаете событие.


epoll - Это набор syscalls, а не библиотека. Когда вы вызываете epoll syscalls вы входите в ядро, и ядро обычно не доверяет этим буферам пользовательского режима обязательно быть действительными или придерживаться, а скорее копирует в память ядра через copy_from_user etc. Так что да, вы можете настроить структуры в стеке, передать их адреса в syscall, а затем отбросить их после его возвращения.