EPOLL SELECT BIO
2021-05-10 16:22:05 0 举报
EPOLL SELECT BIO
作者其他创作
大纲/内容
进程A
进程B
tcp/ip协议
用户空间
内核地址
DATA读缓冲区
内核堆栈 保存一些变量之类的
运行队列
将报文从网卡缓冲区转移到对应的socket读缓冲区内
用户地址 处理80中断进入内核地址
移除
网卡中断处理程序逻辑图02
假设 进程A执行如下代码 伪代码: ...... 客户端socket,读数据(buffer); ......
假设此时外部系统响应
DATA写缓冲区
外部系统
socket等待队列
处理80中断
1. 保存进程用户态堆栈信息到进程描述符
进程描述符PCB
........................................
cpu
通信报文
socket-1端口8818
BIO通信过程
RAM
客户端socket
注意此时读缓冲区中已经有数据了
服务器内存
进程C
网卡中断处理程序逻辑图03
IRQ 中断程序入口映射表(内核启动阶段完成加载)向量值 代码段地址 *描述0 0x88590101 时钟中断处理入口1 0x88487777 键盘中断处理入口2 0x88487777 xxx中断处理入口3 0x88481221...... 0x8848786915 0x88485432 网卡中断程序入口...... 0x88484567128 0x88486789 system_call程序入口
网卡缓冲区
内核进程
等待队列
内核地址 system_call
socket-2端口8819
服务器网卡
TCP/IP报文一定拥有端口号
进程D
网卡发起硬件终端IRQ
HEAD
网卡中断处理程序逻辑图01
拿到结果返回
A寄存器 保存代码地址
system_call(){ int sys_num = 获取eax寄存器的值; func* fun = 获取系统指针函数(sys_num); //将数据从寄存器拷贝到内核空间中。 obj[] objects = 读取传递的参数(); results = fun(objects); //将结果保存到cpu寄存器; setResults(results);}
抢占
到cpu中c寄存器中根据向量找到具体的堆栈地址
bio 问题 难以解决C10K C100K问题
socket-N端口xxxx
系统函数Cfun(){}
。。。。。。。、
u_addr 向量........k_addr 向量........
网卡中断处理程序.............................................
没有数据可读取....
用户程序..................网卡中断...........................
系统函数N....
4. 执行网卡中断处理程序
0x80中断处理程序
DMA存放报文完成
执行
根据地址找到代码入口
用户堆栈 保存一些变量之类的
申请xx资源(xx){ ...... /** *设置eax寄存器系统调用号:198; *将参数xx封装成指针保存到cpu某特定的寄存器中 *保存当前线程的上下文信息到进程描述符 *切换到进程内核栈; *根据映射表加载system_call的地址到寄存器.. */ int 0x80; ...... ...... /** * 将进程描述符中 用户态 的数据恢复到cpu各个寄存器内 * 这一步完成之后 程序将进入用户态 * *恢复现场 */ // 读取系统调用执行结果 从特殊的几个寄存器内读取结果 // 把数据从内核空间拷贝到用户空间 results = 读取系统调用结果(); return results;}
普通代码1;普通代码2;申请xx资源(xx)//比如硬件资源;普通代码3;普通代码4;......
断开
B寄存器 保存代码行号
C寄存器 堆栈地址
因为来一个进程开启一个socket 但是大部分socket是在阻塞状态的所以很浪费cpu资源
里面有一个DMA内嵌设备 无需cpu参与
系统函数D
内核空间
进程A在该等待队列中出队 前往运行队列
系统函数A
系统函数B
进程A阻塞
对端socket
进程A放入等待队列
执行具体函数
2. 修改cpu寄存器 将堆栈指针指向当前进程内核态堆栈 切换到内核态
返回用户态
处理
3. 根据IRQ向量到向量表中查找合适的中断处理程序 放到cpu寄存器A中
线程A再次回到运行队列,对应进程的状态变为“待运行”状态 也就是说 再次有机会获取CPU执行权!!!
网卡发起硬件终端之后 此时是进程B在cpu中运行 此时进程B就会响应中断 此时进程B该干什么呢
0 条评论
下一页