- 论坛徽章:
- 11
|
本帖最后由 zylthinking 于 2013-05-09 18:49 编辑
重温 epoll, 同时给之前研究 epoll 的几位看看, 上次读 epoll 还是因为那几个帖子。
epoll 现在仍然还是有惊群现象的, 但这不是大问题, 因为导致惊群出现的用法已经怎么看怎么不合理了: 如果你将同一个 fd 加入不同的 epollfd, 那么不管你怎么设置属性, 包括前段时间热炒的大招 EPOLLONESHOT, 都避免不了。 好的是, 谁也不会这么干。
epoll 实现基本数据结构有三个, eventpoll, epoll_item, epoll_entry
eventpoll 对应 epollfd
epoll_item 对应加入到某个 epoll 的 fd 实例, 如果同一个 fd 加入多个 epollfd, 则存在多个 epoll_item
epoll_entry 和 epoll_item 一一对应。
相互之间关系为, eventpoll 中保存 epoll_item 链表, epoll_item 和 epoll_entry 一一对应, 通过 epoll_entry 加入到 fd 对应的 file_struct 的 wait 队列。
一旦 fd 有事件了, 通过 wait_list 到达 epoll_entry 然后最终到达 eventpoll, 然后在 epoll_wait 的线程唤醒, 将事件写入用户空间。
这里有个 eventpoll 级别的锁,因此就算多个 epoll_wait 唤醒, 最终只有一个会得到事件, 剩下的空转一圈接着睡眠, 这就是 epoll_wait 为何不惊群的原因, 但要注意不惊群是针对同一个 eventpoll 而言的, 对不同 eventpoll, 是没办法的。
EPOLLONESHOT 是 epoll_item 级别的, 设置方是获得了事件的那个线程, 由于 epoll_item 局限于 eventpoll, 因此 EPOLLONESHOT 也不能阻止同时存在于另一个 epollfd 的 fd 上出现事件, 而导致惊群。 |
|