Linux Epoll介绍和程序实例

匿名 (未验证) 提交于 2019-12-02 21:59:42
1. Epoll是何方神圣?


其实在Linux下设计并发网络程序,向来不缺少方法,比如典型的Apache模型(Process Per Connection,简称PPC),TPC(Thread PerConnection)模型,以及select模型和poll模型,那为何还要再引入Epoll这个东东呢?那还是有得说说的…

如果不摆出来其他模型的缺点,怎么能对比出Epoll的优点呢。

2.1 PPC/TPC模型

这两种模型思想类似,就是让每一个到来的连接一边自己做事去,别再来烦我。只是PPC是为它开了一个进程,而TPC开了一个线程。可是别烦我是有代价的,它要时间和空间啊,连接多了之后,那么多的进程/线程切换,这开销就上来了;因此这类模型能接受的最大连接数都不会高,一般在几百个左右。

2.2 select模型

2.3 poll模型

基本上效率和select是相同的,select缺点的2和3它都没有改掉。

3. Epoll的提升

把其他模型逐个批判了一下,再来看看Epoll的改进之处吧,其实把select的缺点反过来那就是Epoll的优点了。

4. Epoll为什么高效

Epoll的高效和其数据结构的设计是密不可分的,这个下面就会提到。

首先回忆一下select模型,当有I/O事件到来时,select通知应用程序有事件到了快去处理,而应用程序必须轮询所有的FD集合,测试每个FD是否有事件发生,并处理事件;代码像下面这样:

int

if(res > 0)

{

for(int

{

if(FD_ISSET(allConnection[i],&readfds))

{

handleEvent(allConnection[i]);

}

}

}

// if(res == 0) handle timeout, res < 0 handle error

Epoll不仅会告诉应用程序有I/0事件到来,还会告诉应用程序相关的信息,这些信息是应用程序填充的,因此根据这些信息应用程序就能直接定位到事件,而不必遍历整个FD集合。

res = epoll_wait(epfd, events, 20, 120);

for(int

{

handleEvent(events[n]);

}

5. Epoll关键数据结构

前面提到Epoll速度快和其数据结构密不可分,其关键数据结构就是:

epoll_event {

// Epoll events

// User datavariable

};

typedefunion

void

int

__uint32_t u32;

__uint64_t u64;

} epoll_data_t;

可见epoll_data是一个union结构体,借助于它应用程序可以保存很多类型的信息:fd、指针等等。有了它,应用程序就可以直接定位目标了。

既然Epoll相比select这么好,那么用起来如何呢?会不会很繁琐啊…先看看下面的三个函数吧,就知道Epoll的易用了。

epoll_create(int

生成一个Epoll专用的文件描述符,其实是申请一个内核空间,用来存放你想关注的socket fd上是否发生以及发生了什么事件。size就是你在这个Epoll fd上能关注的最大socket fd数,大小自定,只要内存足够。

epoll_ctl(intintintstructepoll_event *event);

控制某个Epoll文件描述符上的事件:注册、修改、删除。其中参数epfd是epoll_create()创建Epoll专用的文件描述符。相对于select模型中的FD_SET和FD_CLR宏。

epoll_wait(intstructepoll_event * events,intint

等待I/O事件的发生;参数说明:

epoll_event:用于回传代处理事件的数组;

maxevents:每次能处理的事件数;

timeout:等待I/O事件发生的超时值;

返回发生事件数。

相对于select模型中的select函数。

下面是一个简单Echo Server的例子程序,麻雀虽小,五脏俱全,还包含了一个简单的超时检查机制,简洁起见没有做错误处理。

  1. usingnamespace
  2. struct
  3. int
  4. voidintintvoid
  5. int
  6. void
  7. int
  8. char
  9. int
  10. long
  11. voidintvoidintintvoidvoid
  12. sizeof
  13. voidintint
  14. struct
  15. int
  16. if
  17. else
  18. if
  19. else
  20. voidint
  21. struct
  22. ifreturn
  23. int
  24. voidintintvoid
  25. voidintintvoid
  26. voidintintvoid
  27. struct
  28. sizeof(struct
  29. int
  30. ifstruct
  31. if
  32. return
  33. do
  34. for
  35. if
  36. break
  37. if
  38. break
  39. int
  40. if
  41. break
  42. while
  43. voidintintvoid
  44. structstruct
  45. int
  46. sizeof
  47. if
  48. '\0'
  49. "C[%d]:%s\n"
  50. elseif
  51. else
  52. voidintintvoid
  53. structstruct
  54. int
  55. if
  56. if
  57. else
  58. voidintshort
  59. int
  60. sizeof
  61. constsizeof
  62. intintchar
  63. short
  64. if
  65. if
  66. struct
  67. int
  68. while
  69. long
  70. for(int
  71. if
  72. ifcontinue
  73. long
  74. if
  75. int
  76. if
  77. break
  78. for(int
  79. struct
  80. if
  81. if
  82. return

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!