使用 libevent2 处理文件 I/O 的问题

Posted

技术标签:

【中文标题】使用 libevent2 处理文件 I/O 的问题【英文标题】:Problem handling file I/O with libevent2 【发布时间】:2011-03-28 09:24:23 【问题描述】:

我使用 libevent2 有一段时间了,但通常我用它来处理网络 I/O(使用套接字)。现在我需要阅读许多不同的文件,所以我也想使用它。我创建了这段代码:

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");

不幸的是,它不起作用。尝试添加事件时收到此消息:

[警告] fd 7 上的 Epoll ADD(1) 失败。旧事件为 0;读取更改为 1(添加);写入更改为 0(无):不允许操作 添加文件事件:不允许操作

文件存在并且有读/写权限。

有人知道如何使用 libevent 处理文件 IO 吗?我也想过缓冲事件,但在 API 中只有函数 bufferevent_socket_new() 在这里不适用。

提前致谢。

【问题讨论】:

【参考方案1】:

我需要 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);

首选项列表中的下一个方法是 poll,它完全支持我想要的文件。

谢谢大家的回答。

【讨论】:

天哪,我浪费了这么多时间试图弄清楚这一点。谢谢【参考方案2】:

libevent 注册常规文件描述符是没有意义的。 File descriptors associated with regular files shall always select true for ready to read, ready to write, and error conditions.

【讨论】:

哦,想要这样的东西很有意义,相信我。你可以通过添加一层间接来获得它,见下文(或上文)。 这与常规文件描述符关系不大。 直接无关,我不敢说反话;但是您仍然可以设法将磁盘 i/o 集成到现有的事件循环中,这可能会消除一些复杂性、减少响应时间等(例如静态、只读 http 文件服务的情况)【参考方案3】:

如果你想做异步磁盘 i/o,你可能需要检查 aio_* 系列(参见 man (3) aio_read)。它是 POSIX.1-2001 并且在 linux 和 bsd 上可用(至少)。

关于将 aio 操作与 libevent 集成,请参阅 libevent aio patch 和 related *** post,其中提到使用 signalfd(2) 将 aio 信号事件路由到可与各种 fd 事件轮询实现一起使用的文件描述符(隐含地与libevent 循环)。

编辑:libevent 还具有信号处理支持(完全忘记了这一点),因此您可以尝试使用/从 libevent 循环直接注册/处理 aio 信号。如果您的开发规则允许,我会亲自去尝试 libevent 补丁。

【讨论】:

以上是关于使用 libevent2 处理文件 I/O 的问题的主要内容,如果未能解决你的问题,请参考以下文章

Erlang I/O处理

如何为多个文件处理选择最佳 I/O 策略?

libevent2 中的分块响应

Libevent 和文件 I/O

EventFD 可以与 libEvent2 一起使用吗?

在 C 中处理从文件 I/O 中存储的字符串的问题