主要通过以下10个方面来了解协程的原理:
为什么会有协程,协程解决什么问题?协程的原语协程的切换协程的运行流程- 协程的结构体定义
- 协程调度的策略
- 协程调度器如何定义
- 协程api的实现,hook
- 协程的多核模式
- 协程如何测试
1-4在《协程的设计与汇编实现》中已经介绍过。本文主要介绍6-10
协程结构体定义
struct coroutine {
struct cpu_register_set *set; // 保存CPU寄存器组
void *func; // coroutine_entry, 协程入口函数
void *arg;
void *retval; // 协程返回值,协程如果不做计算相关的,可以不要返回值;做io可以不需要
void *stack_addr; // 协程栈,函数调用的作用;存储一对大括号内的临时变量;调用一次压栈,return出栈
size_t stack_size;
// 共享栈 or 独立栈
// 共享栈,也叫全局栈,所有协程共用一个栈。隔离性比较差,不推荐。实现很麻烦
// 独立栈,每个协程分配独立空间
//struct coroutine *next;
queue_node(ready_queue, coroutine) *ready;
rbtree_node(coroutine) *wait; // 等待io操作
rbtree_node(coroutine) *sleep; // optional
};
struct cpu_register_set *set;,用来保存CPU寄存器组;
func和arg,表示协程的入口函数和参数。
协程创建与线程类似,coroutine_create(entry_cb, arg);。
线程创建,pthread_create(&thid, NULL, entry_cb, arg);; 在内核里面创建一个线程实体,并把它加入到就绪队列;entry_cb的调用,跟pthread_create没有关系。它的调用,是因为调度器抓取了一个线程,开始运行。
void *retval;,协程返回值,协程如果不做计算相关的,可以不要返回值;**做io可以不需要,**我们实现的时候,没有实现返回值。返回值可以参考线程的方式。
线程的返回值通过pthread_join(pthread_t thread, void **retval)获取到,线程的返回值存在这里,等待子线程退出,或者子线程返回的值。
父协程如果如果要获取子协程的返回值,可以用类似的方式:
// 父协程中进行join
coroutine_join(coid, &ret) {
co = search(coid)
while (co->ret == NULL) {
wait

最低0.47元/天 解锁文章
209

被折叠的 条评论
为什么被折叠?



