• 2.3.1 协程设计原理与汇编实现


    1.为什么要有协程?
    同步的编程方式,异步的性能。同步编程时,我们需要等待io就绪。但是在协程这里,我们使用一种机制,当io需要等待时,就切到下一个io,之后当之前的io就绪时,再切换回来继续处理就绪事件。
    2.协程的原语操作
    yield 让出
    resume 恢复
    3.协程的切换
    切换有三种方式
    1.setjmp/longjmp
    2.ucontext
    3.asm code

    汇编实现切换的优缺点
    1.性能较高
    2.容易理解
    3.容易实现
    a.有门槛
    b.不同体系机构,汇编代码不一样
    c.跨平台较弱

    4.协程的struct如何定义
    5.协程的scheduler如何定义
    6.调度策略如何实现
    7.如何与posix api兼容
    8.协程多核模式
    9.协程的性能如何测试?

    sync() {
    	send(request);
    	recv(response);
    }
    
    • 1
    • 2
    • 3
    • 4
    response_cb() {
    	recv();
    }
    
    async() {
    	send(request, response_cb);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    #include 
    #include 
    //ucontext
    
    //getcontext(&context)
    //makecontext(&context, func, arg);
    //swapcontext(¤t_context, &next_context);
    ucontext_t ctx[2];
    ucontext_t main_ctx;
    int count = 0;
    
    //12314
    void fun1() {
    	while(count++ < 100) {
    		printf("1");
    		swapcontext(&ctx[0], &ctx[1]);
    		printf("3");
    	}
    }
    
    void func2() {
    	while(count++ < 100) {
    		printf("2");
    		swapcontext(&ctx[1], &ctx[0]);
    		printf("4");
    	}
    }
    
    int main() {
    	char stack1[2048] = {0};
    	char stack2[2048] = {0};
    	
    	getcontext(&ctx[0]);
    	ctx[0].uc_stack.ss_sp = stack1;
    	ctx[0].uc_stack.ss_size = sizeof(stack1);
    	ctx[0].uc_link = &main_ctx;
    	makecontext(&ctx[0], fun1, 0);
    
    	getcontext(&ctx[1]);
    	ctx[1].uc_stack.ss_sp = stack1;
    	ctx[1].uc_stack.ss_size = sizeof(stack1);
    	ctx[1].uc_link = &main_ctx;
    	makecontext(&ctx[1], fun2, 0);
    
    	printf("swapcontext\n");
    	swapcontext(&main_ctx, &ctx[0]);
    	printf("\n");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    jmp_buf env;
    //setjmp, longjmp
    
    void func(int arg) {
    	printf("func\n");
    	longjmp(env, ++arg);
    	printf("longjmp complete\n");
    }
    
    int main() {
    	int ret = setjmp(env);
    	if (ret == 0) {
    		printf("ret == 0\n");
    		func(ret);
    	} else if (ret == 1) {
    		printf("ret == 1\n");
    		func(ret);
    	}
    	printf("ret : %d\n", ret);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • 相关阅读:
    C++标准模板(STL)- 类型支持 (运行时类型识别,type_info )
    2.4_4 死锁的检测和解除
    阿里云Docker配置镜像加速器
    K8S控制器
    当 xxl-job 遇上 docker → 它晕了,我也乱了!
    zustand管理工具--React
    谈谈我的「数字文具盒」 - 生产力工具(上)
    谈谈JMM
    CocoaPods 无法使用(Xcode 14.0)
    【数据结构】—— 单调栈
  • 原文地址:https://blog.csdn.net/gaoyuelon/article/details/134025784