100% загрузка ЦП с libev
У меня есть TCP-сервер, который использует libev в качестве цикла событий; для новых принятых розеток я установил:
ev_io_init(&conn->io, tcp_conn_on_event_cb, conn->fd, EV_READ | EV_WRITE);
когда приходит новое соединение, мой сервер потребляет все циклы процессора, у меня загрузка процессора 100%. моя программа все время вызывает обратный вызов tcp_conn_on_event_cb с заданным значением 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
....
Есть ли решение этой проблемы, пожалуйста?
1 ответ
Я нашел решение, для тех, кто интересуется этим вопросом:
при приеме нового сокета не вызывайте ev_io_init с EV_WRITE, вызывайте его только с 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 */
}