poller模块设计要点
高并发服务器中poller模块负责监听文件描述符事件,是事件驱动模型的核心组件。以下为仿muduo库实现的关键设计要素:
接口抽象设计
采用抽象基类定义统一接口,支持不同系统下的具体实现(如epoll/poll/select)。关键接口包括:
poll(int timeoutMs, ChannelList* activeChannels):阻塞等待事件就绪updateChannel(Channel* channel):更新监听的事件类型removeChannel(Channel* channel):移除事件监听
class Poller {
public:
virtual ~Poller() = default;
virtual Timestamp poll(int timeoutMs, ChannelList* activeChannels) = 0;
virtual void updateChannel(Channel* channel) = 0;
virtual void removeChannel(Channel* channel) = 0;
};
事件分发机制
通过Channel对象封装文件描述符及其关注的事件(可读/可写/错误等),每个Channel绑定回调函数。当事件发生时,poller将就绪的Channel加入活动列表:
struct pollfd {
int fd;
short events;
short revents;
};
void EpollPoller::fillActiveChannels(int numEvents, ChannelList* activeChannels) {
for (int i = 0; i < numEvents; ++i) {
Channel* channel = static_cast<Channel*>(events_[i].data.ptr);
channel->set_revents(events_[i].events);
activeChannels->push_back(channel);
}
}
高效IO复用实现
Linux环境下优先使用epoll实现,关键操作包括:
- 创建epoll实例:
epoll_create1(EPOLL_CLOEXEC) - 事件注册/修改:
epoll_ctl(epollfd_, EPOLL_CTL_ADD/MOD, fd, &event) - 事件等待:
epoll_wait(epollfd_, events_, maxEvents, timeout)
void EpollPoller::update(int operation, Channel* channel) {
struct epoll_event event;
memset(&event, 0, sizeof event);
event.events = channel->events();
event.data.ptr = channel;
epoll_ctl(epollfd_, operation, channel->fd(), &event);
}
线程安全考虑
poller模块通常运行在IO线程中,需保证:
- 所有文件描述符操作都在同一线程执行
- Channel的更新通过事件队列跨线程传递
- 使用
eventfd实现线程间唤醒
void EventLoop::wakeup() {
uint64_t one = 1;
ssize_t n = ::write(wakeupFd_, &one, sizeof one);
}
性能优化技巧
- 采用边缘触发(ET)模式减少epoll调用次数
- 使用
vector预分配事件数组避免频繁内存分配 - 实现ChannelMap快速查找文件描述符对应Channel
- 支持批量更新操作减少系统调用
class EPollPoller {
private:
typedef std::vector<struct epoll_event> EventList;
EventList events_;
std::unordered_map<int, Channel*> channels_;
};
错误处理机制
- EINTR信号中断处理:自动重启系统调用
- 文件描述符耗尽保护:限制最大连接数
- 异常情况日志记录:使用LOG_ERROR输出错误信息
while (true) {
int ret = ::epoll_wait(epollfd_, &*events_.begin(),
static_cast<int>(events_.size()), timeoutMs);
if (ret < 0) {
if (errno == EINTR) continue;
LOG_ERROR("epoll_wait error");
break;
}
// ...正常处理逻辑
}
该设计实现了跨平台的事件监听能力,单机可支持数万并发连接,是构建高性能网络服务的核心基础设施模块。
670

被折叠的 条评论
为什么被折叠?



