简述epoll实现

所有学习笔记:https://github.com/Dusongg/StudyNotes

epoll数据结构的选择?

  • rbtree/hash/btree/b+tree?
    • hash内存浪费

epoll内核为什么不选择哈希表而是选择红黑树?

在Linux的epoll中,为了实现高效的事件管理,epoll内核模块采用了红黑树作为事件的存储结构,而不是哈希表。这是因为红黑树在查找、插入和删除等操作上具有较好的性能表现,特别是对于大量事件的管理。

红黑树是一种自平衡的二叉查找树,具有以下特点:

  1. 在最坏情况下,插入、删除和查找操作的时间复杂度为O(log n),保证了较好的性能。
  2. 红黑树的结构相对稳定,对于动态添加和删除节点的场景,红黑树能够保持平衡,减少了不必要的树旋转操作。
  3. 红黑树的高度较低,使得在进行查找操作时能够快速定位到目标节点。

相比之下,哈希表虽然在平均情况下具有O(1)的插入、删除和查找操作,但在处理大规模数据时,哈希表的冲突处理、扩容和缩小等操作会引入额外的开销,而且哈希表的遍历不如红黑树高效,因此在这种场景下,红黑树更适合作为epoll的事件管理数据结构

  • btree/b+tree更适合磁盘查找

所以最终

io集合用红黑树管理;就绪集合用队列管理;队列和红黑树公用一个节点

image-20240309234541225

image-20240310001744630

以tcp为例,网络io的可读可写如何判断?

  1. 对于tcp而言,哪些事件是的io变为就绪:

    1. 三次握手完成 -> listenfd可读

    2. 当recvbuffer接收到数据 -> clientfd可读

      image-20240310004908826

    3. 当sendbuffer有空间 -> clientfd可写

    4. 当接收到FIN包 -> clientfd可读

epoll如何做到线程安全?

一把锁锁rbtree -> mutex:得不到锁,休眠

一把锁锁queue -> spinlock :得不到锁,一直等待

自旋锁和互斥锁都是用于多线程编程中实现同步的机制,但它们有一些区别:

  1. 等待方式
    • 自旋锁:线程在尝试获取锁时,如果锁已经被其他线程持有,该线程会一直处于忙等(自旋)状态,直到锁被释放。
    • 互斥锁:线程在尝试获取锁时,如果锁已经被其他线程持有,该线程会被阻塞,直到锁被释放。
  2. 实现机制
    • 自旋锁:通常使用原子操作来实现,因此适用于轻量级的同步操作。
    • 互斥锁:通常使用操作系统提供的系统调用(如pthread_mutex_lock)来实现,因此会涉及到用户态和内核态的切换,性能开销较大。
  3. 适用场景
    • 自旋锁:适用于锁被持有的时间很短的情况,避免了线程切换的开销。
    • 互斥锁:适用于锁被持有的时间较长的情况,可以让等待的线程进入睡眠状态,不会占用CPU资源。
  4. 实现复杂度
    • 自旋锁:实现相对简单,主要依赖于原子操作。
    • 互斥锁:实现相对复杂,需要考虑线程阻塞、唤醒等操作。

LT和ET如何实现?

tcp内部有一个循环,内核recvbuffer。

  • LT判断recvbuffer有数据就回调,往就绪队列里增加节点,节点状态为就绪

  • ET判断有数据写入recvbuffer才回调,往队列里增加节点,节点状态为就绪

image-20240310001521549

tcp状态和io的读写有哪些关系?

tcp调用回调函数,将事件添加到就绪队列

epoll中实现回调函数,当回调函数被tcp调用时,pthread_cond_signal唤醒epoll_wait中的条件变量

image-20240310010432071

epoll_wait等待io唤醒过程(以建立tcp建立链接为例)

image-20240310005922431
ll_wait等待io唤醒过程(以建立tcp建立链接为例)

[外链图片转存中…(img-YvWU16DH-1710004476688)]

相关推荐

  1. epoll timer实现定时任务

    2024-03-12 04:34:04       46 阅读
  2. epoll_socket

    2024-03-12 04:34:04       63 阅读
  3. 小试epoll

    2024-03-12 04:34:04       33 阅读
  4. Linux内核--网络协议栈(九)epoll的源码实现

    2024-03-12 04:34:04       49 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-12 04:34:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-12 04:34:04       101 阅读
  3. 在Django里面运行非项目文件

    2024-03-12 04:34:04       82 阅读
  4. Python语言-面向对象

    2024-03-12 04:34:04       91 阅读

热门阅读

  1. 开发指南002-前后端信息交互规范-返回值定义

    2024-03-12 04:34:04       49 阅读
  2. 常用的推荐算法

    2024-03-12 04:34:04       46 阅读
  3. ARM TrustZone技术介绍

    2024-03-12 04:34:04       40 阅读
  4. linux新一代的RPM软件包管理器dnf

    2024-03-12 04:34:04       50 阅读
  5. Linux中basename作用

    2024-03-12 04:34:04       46 阅读
  6. Dutree:Linux 文件系统磁盘使用追踪工具

    2024-03-12 04:34:04       41 阅读