Проблемы с файловым вводом-выводом при помощи libevent2

Некоторое время я работал с libevent2, но обычно я использовал его для обработки сетевого ввода-вывода (с использованием сокетов). Теперь мне нужно прочитать много разных файлов, поэтому я тоже хотел его использовать. Я создал этот код:

int file = open(filename, O_RDONLY);
struct event *ev_file_read = event_new(ev_base, file, EV_READ | EV_PERSIST, read_file, NULL);

if(event_add(ev_file_read, NULL))
        error("adding file event");

К сожалению, это не работает. Я получаю это сообщение при попытке добавить событие:

[предупреждение] Ошибка Epoll ADD (1) на fd 7. Старых событий было 0; прочитанное изменение было 1 (добавить); изменение записи было 0 (нет): операция не разрешена событие добавления файла: операция не разрешена

Файл существует и имеет права на чтение / запись.

Кто-нибудь знает, как обрабатывать файловый ввод-вывод с помощью libevent? Я думал также о буферных событиях, но в API есть только функция bufferevent_socket_new (), которая здесь не применяется.

Заранее спасибо.


person harnen    schedule 28.03.2011    source источник


Ответы (3)


Libevent был нужен мне для чтения множества файлов, касающихся приоритетов. Проблема была в epoll, а не в libevent. Epoll не поддерживает обычные файлы Unix.

Чтобы решить эту проблему, я заставил libevent не использовать epoll:

    struct event_config *cfg = event_config_new();

event_config_avoid_method(cfg, "epoll");

ev_base = event_base_new_with_config(cfg);  
    event_config_free(cfg);

Следующим методом в списке предпочтений был опрос, который полностью поддерживает файлы, как я и хотел.

Всем спасибо за ответы.

person harnen    schedule 29.03.2011
comment
о боже, я потратил столько времени, пытаясь понять это. Благодарность - person c00kiemon5ter; 04.04.2012

Нет смысла регистрировать обычные файловые дескрипторы с libevent. Файловые дескрипторы, связанные с обычными файлами, всегда должны выбирать true для готовности к чтению, готовности к записи, и условия ошибки.

person Maxim Egorushkin    schedule 28.03.2011
comment
о, поверьте, есть смысл хотеть этого. и вы можете получить это, добавив один уровень косвенности, см. ниже (или выше). - person user237419; 28.03.2011
comment
Это не имеет ничего общего с обычным файловым дескриптором. - person Maxim Egorushkin; 29.03.2011
comment
прямо не при чем, я не осмелюсь сказать обратное; но вы все равно можете интегрировать дисковый ввод-вывод в существующий цикл событий, и это может устранить некоторую сложность, уменьшить время отклика и т. д. (например, в случае статической файловой службы http только для чтения) - person user237419; 29.03.2011

если вы хотите выполнять асинхронный ввод-вывод диска, вы можете проверить семейство aio_ * (см. man (3) aio_read). это POSIX.1-2001 и доступен на linux и bsd (по крайней мере).

для интеграции операций aio с libevent см. libevent aio patch и связанного сообщения stackoverflow, в котором упоминается использование signalfd (2) для маршрутизации событий сигнала aio в файловый дескриптор, который может использоваться с различными реализациями опроса событий fd (так неявно с помощью цикла libevent).

РЕДАКТИРОВАТЬ: libevent также поддерживает обработку сигналов (совершенно забыл об этом), поэтому вы можете попробовать зарегистрировать / обработать сигналы aio напрямую с / из цикла libevent. Я лично сначала попробую установить патч libevent, если это позволяют правила разработки.

person user237419    schedule 28.03.2011