Epoll

作者: 帆子_8c3a | 来源:发表于2019-03-08 16:44 被阅读0次

Linux IO类型

参考1
参考2

  • 同步IO Blocking IO
  • 同步IO Nonblocking IO : 需要不停轮询IO是否完成
  • 同步IO Multiplexing IO : 就是我们熟知的select、poll、epoll模型
  • Signal driven IO
  • Asynchronous IO : linux的网络IO中是不存在异步IO的

select的使用

参考代码
select内部会为每个socket查询是否有新数据,如果有进行标记POLL_IN。

缺点:

  1. 是需要把readfds、writefds从用户态拷贝到内核态,因此对fd集合大小限制为1024。
  2. select虽然得到通知,但不知道来自那个fd,因此要遍历所有fd。
int select(int nfds, fd_set *readfds, fd_set *writefds,
            fd_set *exceptfds, struct timeval *timeout);

集合相关的宏:

  • FD_ZERO()
  • FD_SET() //add
  • FD_CLR() //remove
  • FD_ISSET() //test
int ns1 = accept(...);
int ns2 = accept(...);
int maxfd = max(ns1,ns2)+1;
for(;;)
{
    FD_ZERO(&fds);
    FD_SET(ns1,&fds);
    FD_SET(ns2,&fds);
    select(maxfd, &fds, NULL, NULL,NULL);
    if( FD_ISSET(ns1, &fds))
    {
        //come from 1
        recv(ns1, buf, sizeof(buf), 0);
    }
    if( FD_ISSET(ns2, &fds))
    {
        //come from 2
        recv(ns2, buf, sizeof(buf), 0);
    }
}

poll的使用

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

poll没有使用select的fd_set,而是采用了pollfd数据结构。解决了1024的限制问题。但还是需要遍历所有fd。

epoll的使用

参考代码
优点:

  1. 高频的epoll_wait和低频的epoll_ctl隔离开。epoll_ctl的操作分为EPOLL_CTL_ADD、EPOLL_CTL_MOD、EPOLL_CTL_DEL
  2. epoll使用了mmap,避免了用户态和内核态之间的内核拷贝。
  3. epoll使用红黑树来表示返回的fd集合。

相关文章

网友评论

      本文标题:Epoll

      本文链接:https://www.haomeiwen.com/subject/yrzrpqtx.html