关于epoll和splice的问题

时间:2010-11-13 14:35:03

标签: linux tcp epoll splice

我的应用程序将通过网络发送大量数据,因此我决定(因为我使用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. 文件描述符必须首先变为可读,并且在套接字变为可写之前会有一些间隔。我可以确定,当套接字变为可写时,文件描述符仍然是可读的(以避免阻塞调用)?

2 个答案:

答案 0 :(得分:2)

第一个问题

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

    文件描述符必须首先变为可读,并且在socket变为可写之前会有一段时间间隔。

    什么样的文件描述符?如果文件系统上的此文件无法使用select / poll或其他工具来实现此目的,则无论磁盘和缓存如何,文件都将始终可读或可写。如果您需要异步工作人员,您可以使用aio_* API,但通常只是从文件写入文件读取并假设它是非阻塞的。

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

答案 1 :(得分:1)

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