3

我的应用程序将通过网络发送大量数据,所以我决定(因为我使用的是 Linux)使用 epoll 和 splice。这是我的看法(伪代码):

epoll_ctl (file_fd, EPOLL_CTL_ADD); // waiting for EPOLLIN event
while(1)
{
    epoll_wait (tmp_structure);

    if (tmp_structure->fd == file_descriptor)
    {
        epoll_ctl (file_fd, EPOLL_CTL_DEL); 
        epoll_ctl (tcp_socket_fd, EPOLL_CTL_ADD); // wait for EPOLLOUT event
    }

    if (tmp_structure->fd == tcp_socket_descriptor)
    {
        splice (file_fd, tcp_socket_fd);
        epoll_ctl (tcp_socket_fd, EPOLL_CTL_DEL); 
        epoll_ctl (file_fd, EPOLL_CTL_ADD); // waiting for EPOLLIN event
    }
}

我假设我的应用程序将打开多达 2000 个 TCP 套接字。我想问你两件事:

  1. 会有相当多的epoll_ctl调用,当我有这么多套接字时会不会很慢?
  2. 文件描述符必须首先变得可读,并且在套接字变为可写之前会有一些时间间隔。我可以确定,在套接字变为可写文件描述符的那一刻仍然是可读的(以避免阻塞调用)?
4

2 回答 2

2

第一个问题

  1. 您可以使用边缘触发而不是触发轮询,因此您不必每次都删除套接字。
  2. 您可以使用 EPOLLONESHOT 来防止移除套接字

文件描述符必须首先变得可读,并且在套接字变为可写之前会有一些时间间隔。

什么样的文件描述符?如果文件系统上的这个文件你不能使用 select/poll 或其他工具来达到这个目的,无论磁盘和缓存状态如何,文件都将始终是可读或可写的。如果您需要异步执行人员操作,您可以使用aio_*API,但通常只是从文件读取到文件并假设它是非阻塞的。

如果它是 TCP 套接字,那么它大部分时间都是可写的。当你得到 EWOULDBLOCK 时,最好使用非阻塞调用并将套接字放入 epoll。

于 2010-11-13T20:27:29.283 回答
1

考虑使用 EPOLLET 标志。这绝对是针对这种情况的。使用此标志时,您可以以正确的方式使用事件循环,而无需从 epoll 中首次注册后取消注册(或修改模式)文件描述符。:) 请享用!

于 2014-02-16T23:03:10.030 回答