博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
epoll源码分析(一)
阅读量:2224 次
发布时间:2019-05-08

本文共 1881 字,大约阅读时间需要 6 分钟。

当系统启动时,epoll进行初始化:

  1. static int __init eventpoll_init(void)
  2. {

  3.     mutex_init(&pmutex);
  4.     ep_poll_safewake_init(&psw);
  5.     epi_cache = kmem_cache_create(“eventpoll_epi”,sizeof(struct epitem),
  6.             0,SLAB_HWCACHE_ALIGN|EPI_SLAB_DEBUG|
  7.             SLAB_PANIC,NULL);
  8.     pwq_cache = kmem_cache_create(“eventpoll_pwq”,sizeof(struct
  9.              eppoll_entry),0,EPI_SLAB_DEBUG|SLAB_PANIC,NULL);
  10.     
  11.     return 0;
  12. }

上面的代码实现一些数据结构的初始化,通过fs/eventpoll.c中的注释可以看出,有三种类型的锁机制使用场景:

1.epmutex(mutex):用户关闭文件描述符,但是没有调用EPOLL_CTL_DEL

2.ep->mtx(mutex):用户态与内核态的转换可能会睡眠

3.ep->lock(spinlock):内核态与具体设备中断过程中的转换,poll回调

接下来就是使用slab分配器动态分配内存,第一个结构为当系统中添加一个fd时,就创建一epitem结构体,内核管理的基本数据结构:

  1. struct epitem
  2. {

  3.     struct rb_node rbn;//用于主结构管理的红黑树
  4.     struct list_head rdllink;//事件就绪队列
  5.     struct epitem *next;//用于主结构体中的链表
  6.     struct epoll_filefd ffd;//每个fd生成的一个结构
  7.     int nwait;//
  8.     struct list_head pwqlist;//poll等待队列
  9.     struct eventpoll *ep;//该项属于哪个主结构体
  10.     struct list_head fllink;//链接fd对应的file链表
  11.     struct epoll_event event;//注册的感兴趣的事件,也就是用户空间的epoll_event
  12.     }

而每个epoll fd对应的主要数据结构为:

  1. struct eventpoll {

  2.     spin_lock_t lock;//对本数据结构的访问
  3.     struct mutex mtx;//防止使用时被删除
  4.     wait_queue_head_t wq;//sys_epoll_wait() 使用的等待队列
  5.     wait_queue_head_t poll_wait;//file->poll()使用的等待队列
  6.     struct list_head rdllist;//事件满足条件的链表
  7.     struct rb_root rbr;//用于管理所有fd的红黑树
  8.     struct epitem *ovflist;//将事件到达的fd进行链接起来发送至用户空间
  9. }

该结构主要在epoll_create时进行创建:

  1. //原来使用的是hash表,所以有size,现在改为红黑树,故不使用.
  2. long sys_epoll_create(int size)
  3. {

  4.     int error,fd = -1;
  5.     struct eventpoll *ep;
  6.     struct inode *inode;
  7.     struct file *file;
  8.     
  9.     ….
  10.     error = -EINVAL;
  11.     //分配空间
  12.     if(size <= 0 || (error = ep_alloc(&ep)!=0))
  13.         goto errror_return;
  14.     //创建一个struct file结构,由于没有任何文件系统,为匿名文件,
  15.         并将主结构体放入file->private项中进行保存
  16.     error = anon_inode_getfd(&fd,&inode,&file,[eventpoll],
  17.             &eventpoll_fops,ep);
  18.     if(error)
  19.         goto error_free;
  20.     return fd;
  21.     ...
  22. }

上面注册的操作eventpoll_fops定义如下:

  1. static const struct file_operations eventpoll_fops = {

  2.     .release     =     ep_eventpoll_release;
  3.     .poll        =    ep_eventpoll_poll,
  4. }

这样说来,内核中维护了一棵红黑树,大致的结构如下:

转载地址:http://gwafb.baihongyu.com/

你可能感兴趣的文章
用学习曲线 learning curve 来判别过拟合问题
查看>>
用验证曲线 validation curve 选择超参数
查看>>
用 Grid Search 对 SVM 进行调参
查看>>
用 Pipeline 将训练集参数重复应用到测试集
查看>>
PCA 的数学原理和可视化效果
查看>>
机器学习中常用评估指标汇总
查看>>
什么是 ROC AUC
查看>>
Bagging 简述
查看>>
详解 Stacking 的 python 实现
查看>>
简述极大似然估计
查看>>
用线性判别分析 LDA 降维
查看>>
用 Doc2Vec 得到文档/段落/句子的向量表达
查看>>
使聊天机器人具有个性
查看>>
使聊天机器人的对话更有营养
查看>>
一个 tflearn 情感分析小例子
查看>>
attention 机制入门
查看>>
手把手用 IntelliJ IDEA 和 SBT 创建 scala 项目
查看>>
GAN 的 keras 实现
查看>>
AI 在 marketing 上的应用
查看>>
Logistic regression 为什么用 sigmoid ?
查看>>