当前位置:   article > 正文

仿Muduo库实现高并发服务器——事件监控Poller模块

仿Muduo库实现高并发服务器——事件监控Poller模块

 Poller模块在整个项目的使用

下面代码是对I/O复用接口函数的基本使用。

回顾上篇文章:事件监控管理模块

这个模块是将触发事件的描述符,给到外面,让外面去做对应的处理。

  1. #define MAX_EPOLLEVENTS 1024
  2. class Poller {
  3. private:
  4. int _epfd;
  5. struct epoll_event _evs[MAX_EPOLLEVENTS];
  6. std::unordered_map<int, Channel *> _channels;
  7. private:
  8. //对epoll的直接操作
  9. void Update(Channel *channel, int op) {
  10. // int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev);
  11. int fd = channel->Fd();
  12. struct epoll_event ev;
  13. ev.data.fd = fd;
  14. ev.events = channel->Events();
  15. int ret = epoll_ctl(_epfd, op, fd, &ev);
  16. if (ret < 0) {
  17. ERR_LOG("EPOLLCTL FAILED!");
  18. }
  19. return;
  20. }
  21. //判断一个Channel是否已经添加了事件监控
  22. bool HasChannel(Channel *channel) {
  23. auto it = _channels.find(channel->Fd());
  24. if (it == _channels.end()) {
  25. return false;
  26. }
  27. return true;
  28. }
  29. public:
  30. Poller() {
  31. _epfd = epoll_create(MAX_EPOLLEVENTS);
  32. if (_epfd < 0) {
  33. ERR_LOG("EPOLL CREATE FAILED!!");
  34. abort();//退出程序
  35. }
  36. }
  37. //添加或修改监控事件
  38. void UpdateEvent(Channel *channel) {
  39. bool ret = HasChannel(channel);
  40. if (ret == false) {
  41. //不存在则添加
  42. _channels.insert(std::make_pair(channel->Fd(), channel));
  43. return Update(channel, EPOLL_CTL_ADD);
  44. }
  45. return Update(channel, EPOLL_CTL_MOD);
  46. }
  47. //移除监控
  48. void RemoveEvent(Channel *channel) {
  49. auto it = _channels.find(channel->Fd());
  50. if (it != _channels.end()) {
  51. _channels.erase(it);
  52. }
  53. Update(channel, EPOLL_CTL_DEL);
  54. }
  55. //开始监控,返回活跃连接
  56. void Poll(std::vector<Channel*> *active) {
  57. // int epoll_wait(int epfd, struct epoll_event *evs, int maxevents, int timeout)
  58. int nfds = epoll_wait(_epfd, _evs, MAX_EPOLLEVENTS, -1);
  59. if (nfds < 0) {
  60. if (errno == EINTR) {
  61. return ;
  62. }
  63. ERR_LOG("EPOLL WAIT ERROR:%s\n", strerror(errno));
  64. abort();//退出程序
  65. }
  66. for (int i = 0; i < nfds; i++) {
  67. auto it = _channels.find(_evs[i].data.fd);
  68. assert(it != _channels.end());
  69. it->second->SetREvents(_evs[i].events);//设置实际就绪的事件
  70. active->push_back(it->second);
  71. }
  72. return;
  73. }
  74. };

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/997688
推荐阅读
相关标签
  

闽ICP备14008679号