赞
踩
Poller模块在整个项目的使用
下面代码是对I/O复用接口函数的基本使用。
回顾上篇文章:事件监控管理模块
这个模块是将触发事件的描述符,给到外面,让外面去做对应的处理。
- #define MAX_EPOLLEVENTS 1024
- class Poller {
- private:
- int _epfd;
- struct epoll_event _evs[MAX_EPOLLEVENTS];
- std::unordered_map<int, Channel *> _channels;
- private:
- //对epoll的直接操作
- void Update(Channel *channel, int op) {
- // int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev);
- int fd = channel->Fd();
- struct epoll_event ev;
- ev.data.fd = fd;
- ev.events = channel->Events();
- int ret = epoll_ctl(_epfd, op, fd, &ev);
- if (ret < 0) {
- ERR_LOG("EPOLLCTL FAILED!");
- }
- return;
- }
- //判断一个Channel是否已经添加了事件监控
- bool HasChannel(Channel *channel) {
- auto it = _channels.find(channel->Fd());
- if (it == _channels.end()) {
- return false;
- }
- return true;
- }
- public:
- Poller() {
- _epfd = epoll_create(MAX_EPOLLEVENTS);
- if (_epfd < 0) {
- ERR_LOG("EPOLL CREATE FAILED!!");
- abort();//退出程序
- }
- }
- //添加或修改监控事件
- void UpdateEvent(Channel *channel) {
- bool ret = HasChannel(channel);
- if (ret == false) {
- //不存在则添加
- _channels.insert(std::make_pair(channel->Fd(), channel));
- return Update(channel, EPOLL_CTL_ADD);
- }
- return Update(channel, EPOLL_CTL_MOD);
- }
- //移除监控
- void RemoveEvent(Channel *channel) {
- auto it = _channels.find(channel->Fd());
- if (it != _channels.end()) {
- _channels.erase(it);
- }
- Update(channel, EPOLL_CTL_DEL);
- }
- //开始监控,返回活跃连接
- void Poll(std::vector<Channel*> *active) {
- // int epoll_wait(int epfd, struct epoll_event *evs, int maxevents, int timeout)
- int nfds = epoll_wait(_epfd, _evs, MAX_EPOLLEVENTS, -1);
- if (nfds < 0) {
- if (errno == EINTR) {
- return ;
- }
- ERR_LOG("EPOLL WAIT ERROR:%s\n", strerror(errno));
- abort();//退出程序
- }
- for (int i = 0; i < nfds; i++) {
- auto it = _channels.find(_evs[i].data.fd);
- assert(it != _channels.end());
- it->second->SetREvents(_evs[i].events);//设置实际就绪的事件
- active->push_back(it->second);
- }
- return;
- }
- };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。