3

我有一个使用 libev 作为事件循环的 tcp 服务器;对于我设置的新接受的套接字:

 ev_io_init(&conn->io, tcp_conn_on_event_cb, conn->fd, EV_READ | EV_WRITE);

当一个新的连接到来时,我的服务器消耗了整个 CPU 周期,我有 100% 的 CPU 使用率。我的程序一直调用回调tcp_conn_on_event_cb,并将 revents 设置为 EV_WRITE

static void tcp_conn_on_event_cb(ev_loop_t *loop, ev_io *ev, int revents)

当我做

strace mybinary

我有这个:

epoll_wait(4, {{EPOLLOUT, {u32=7, u64=4294967303}}}, 64, 59743) = 1
epoll_wait(4, {{EPOLLOUT, {u32=7, u64=4294967303}}}, 64, 59743) = 1
epoll_wait(4, {{EPOLLOUT, {u32=7, u64=4294967303}}}, 64, 59743) = 1
epoll_wait(4, {{EPOLLOUT, {u32=7, u64=4294967303}}}, 64, 59743) = 1
epoll_wait(4, {{EPOLLOUT, {u32=7, u64=4294967303}}}, 64, 59743) = 1
epoll_wait(4, {{EPOLLOUT, {u32=7, u64=4294967303}}}, 64, 59743) = 1
epoll_wait(4, {{EPOLLOUT, {u32=7, u64=4294967303}}}, 64, 59743) = 1
                           ....

请问这个问题有解决方案吗?

4

1 回答 1

4

我找到了一个解决方案,对于那些对此问题感兴趣的人:

接受新套接字时,不要使用EV_WRITE调用ev_io_init ,仅使用 EV_READ 调用它。

ev_io_init(&conn->io, tcp_conn_on_event_cb, conn->fd, EV_READ);

在回调中,如果你有数据要写入(到套接字),你可以使用ev_feed_fd_event

static void tcp_conn_on_event_cb(ev_loop_t *loop, ev_io *ev, int revents)
{
      ....

    if (revents | EV_WRITE) {
         /* write your data here */
    }

    if (data_is_ready()) {
        ev_feed_fd_event(loop, conn->fd, EV_WRITE | revents);
        return;
    }

    /* do other job */
}
于 2016-12-07T14:58:26.197 回答