协程设计原理与汇编实现
协程:
1.为什么会有协程,解决什么问题?
2.原语
3.协程的切换
4.协程结构体定义
5.调度的策略
6.调度器如何定义
7.协程api的实现,hook
8.多核模式
9.如何测试
同步的编程方式,异步的性能
如果检测io与读写io在一个流程里面就是同步,如果不在一个流程里面就是异步
//同步 func (){ while(1){ epoll_wait(); for(;;){ recv(); send(); } } }
//伪代码,异步 thread_cb(void *arg){ recv(); send(); } func () { while(1) { epoll_wait(); for(;;) { push_other_thread(); } } }
避免不了一个问题:同一个fd会在不同的线程中操作,解决是在recv前在封装一个poll,检测是否真的可读
协程是在send之后,将fd加入到epoll,然后让出到epoll_wait,这时有两个可能1、epoll_wait没有就绪的,在恢复到send。2、如果有就绪的,处理fd,recv。
协程运行流程:遇到io(send,recv等),resume,操作完后,再yield
goto只能在函数内部跳转。栈内跳转
有三种跳转方式:
1、setjmp/longjmp
2、ucontext
3、汇编
线程切换:先保存当前寄存器的值(save),然后切换到下一个线程(load),相当于保留现场和恢复现场
协程也一样,yield和resume
一个fd对应一个协程作为网络io合适,做页面刷新,文件就不合适
问题:协程的状态应该用什么样的数据结构,新建,等待,就绪,睡眠
新建,就绪用队列
等待睡眠用红黑树,为什么不用小顶堆,因为小顶堆一次只能取一个
struct coroutine{
struct cpu_register_set *set; //cpu
void *func; //coroutine_entry;
void *arg;
void *retval; //返回值
void *stack_addr; //栈,协程独立栈
size_t stack_size; //栈的大小
queue(struct coroutine) *ready;
retree(struct coroutine) *wait;
rebree(struct coroutine) *sleep;//optional
}
所有的协程再就绪队列中都存在,调度的时候首先先判断sleep,然后判断wait,最后判断就绪。因此这几种状态中会有重复的。
hook,可以将系统的函数重定向为自己写的函数,
mysql -->开发接口
1.增删改查
2.存储过程
3.二进制
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构