如何实现一个异步io框架

网卡接收到数据以后

网卡的基础知识

网卡本身是有内存的,每个网卡一般都有4k以上的内存,用来发送、接受数据。数据从主内存搬到网卡之后,不是立即就能被发送出去的,而是要先在网卡自身的内存中排队,再按先后顺序发送,同样的,数据从以太网传递到网卡时,网卡也是先把数据存储到自身的内存中,等到收到一帧数据了,再经过中断的方式,告诉CPU把网卡内存的数据读走(现在网卡大都支持DMA方式直接从网卡内存拷贝被内核内存),而读走后的内存,又被清空,再次被用来接收新的数据。

流程

  1. 数据包从外面的网络进入物理网卡。如果目的地址不是该网卡,且该网卡没有开启混杂模式,该包会被网卡丢弃。
  2. 网卡将数据包通过DMA的方式写入到指定的内存地址,该地址由网卡驱动分配并初始化。
  3. 网卡通过硬件中断(IRQ)通知CPU,告诉它有数据来了
  4. CPU根据中断表,调用已经注册的中断函数,这个中断函数会调到驱动程序(NIC Driver)中相应的函数
  5. 驱动先禁用网卡的中断,表示驱动程序已经知道内存中有数据了,告诉网卡下次再收到数据包直接写内存就可以了,不要再通知CPU了,这样可以提高效率,避免CPU不停的被中断。
  6. 启动软中断。这步结束后,硬件中断处理函数就结束返回了。由于硬中断处理程序执行的过程中不能被中断,所以如果它执行时间过长,会导致CPU没法响应其它硬件的中断,于是内核引入软中断,这样可以将硬中断处理函数中耗时的部分移到软中断处理函数里面来慢慢处理。
  7. 经过TCP/IP协议逐层处理。
  8. 应用程序通过read()从socket buffer读取数据。

socket详细流程

tcp三次握手

setblocking

backlog

syn,accept队列

accept()创建新套接字

协议栈是什么

粘包是个伪命题

buffer缓冲区大小

IO阻塞本质

读缓存,写缓冲区

send,recv原理

满加锁,空解锁

tcp ack滑动窗口

如何确定recv结构是完整的

长链接、短连接区别

socket维护长短连接手段

keepalive心跳包谁维护

高并发模型

fork模型

进程池/线程池模型

io复用模型

惊群、饥饿

上下文

什么是上下文

什么是上下文切换

为什么要上下文切换

什么时候会上下文切换

执行单元

进程、线程、协程

堆、栈

抢占、协作

io

同步、异步、阻塞、非阻塞

fd

一个线程如何管理多个fd

io多路复用

select

poll

epoll

水平触发、边缘触发

跨平台

libevnet

libev

libuv

调度器组成

  1. eventLoop
  2. 类生成器
  3. Fd生成器的关系
  4. 信号处理
  5. 文件属性变化
  6. Io可读可写
  7. 定时器
  8. periodic
  9. timeout

prefork + epoll