协程:
- 为什么会有协程?解决什么问题?
- 原语
- 协程的切换
- 协程结构体定义
- 协程多的时候,调度策略
- 调度器如何定义?
- 协程api的实现,hook
- 多核模式
- 如何测试
(如果把协程写在简历里,主要围绕这九个问题)
服务端:
对网络连接的处理
同步:在同一个流程,也即按顺序执行。
异步:不在同一个流程中执行
同步与异步,是形容两者之间的关系。
检测io与读写io,在同一个流程则为同步,不在同一个流程则为异步。
异步io:aio
io异步操作:指检测io与读写异步操作。
可以一个线程使用多个fd,但要避免多个线程公用一个fd(读数据出现数据错乱);
异步编程方式的麻烦点:多个线程公用一个fd。(但性能高)。
同步编程好处:便于理解,但性能不高。
客户端
对网络连接的处理
同步:客户端发送一个请求,等到服务端返回结果,然后再发送一个,再等待.......
异步:客户端发送请求后,不等待服务端回应,继续操作。
协程就是为了解决同步异步问题,
协程:写代码的时候,是同步的,运行的逻辑是异步的。
以客户端请求服务器为例:
客户端发送请求后,把这个fd放到epoll里面,看是否有事件可读,若没有则切换,继续发送请求,一直循环切换。......
io操作、epoll_wait、io操作、epoll_wait.......之间不断切换
io操作(发送请求)到epoll操作(epoll_wait和读操作)有个跳变切换。
send后跳到epoll_wait,然后再跳回到send操作。
send->yeild(让出)到epoll_wait->resume(恢复)到io操作。
yeild和resume是两个原语操作,实现跳转功能。此处跳转不能用goto,因为共同只能在函数内部跳转。
如何是实现yeild和resume?核心底层共用到switch()函数。用1、setjumt/longjmp 2、ucontext 3、汇编的代码实现
从当前线程跳转到A线程:把当前进程在cpu寄存器的值保存(save)到当前线程的一个存储位置上,然后加载线程A的寄存器组。即可实现切换(在内核中,线程、进程、协程都一样)。即两步操作:save,load
label保存了label在寄存器的值,跳转的时候,在jmp处先保存当前寄存器的值,然后load label寄存器的值。、
协程之间调换也是在一个线程中的
协程运行的时候再在调度器中运行的。
协程是线程内部的