协程的设计原理(一)

简介: 协程的设计原理(一)

1 解决问题

目前主流的协程libgo(golang提供);libco(腾讯开源),libgo使用起来方便,自己的工程也是采用libgo实现的全球同服的服务器框架。解决了采用同步的方式实现异步的性能。

2 同步/异步/协程关系

1 同步与异步区别

对于同步来说是,业务服务器发送一个请求后,等待第三方服务器返回后继续执行其它操作;异步是不需要等待返回,直接执行其它操作,当第三方服务器返回时候,在通过回调方式来通知业务服务器对应响应的处理。

异步的实现方式可以看前面的博客(异步请求池实现)四元组.

2 具体编程实现

不采用线程池和采用线程池的对比

//不采用线程池的大体逻辑
while(1){
  int nready = epoll_wait(); // 检测io
  for(i = 0; i < nready; i++){
    recv();   // 对io操作
      parese(); // 解析buffer
    send();
  }
}
// 加入线程池大体逻辑
void mainloop(){  // 主线程
  while(1){
    int nready = epoll_wait(); 
    for(i = 0; i < nready; i++){
      /*recv(buffer);
        parese();
      send();
      */
      push_to_workqueue(work_cb); // 抛入线程池
    }
  }
}
// 另外一个子线程
void *work_cb(void *arg){
  recv(buffer);
    parese();
  send(buff);
}

注意加线程池的性能大概提升不加线程池的3倍左右。

对于服务器来说,当检查io和读写io是在同一个流程里就叫同步;而不在同一个流程(例如添加线程池后)就叫异步

区别:

同步实现简单,流程清晰符合人的思维方式,效率相对来说不高;

异步实现复杂,效率相对来说较高。

为了中和同步和异步,需要采用同步的方式实现异步的性能,两者优点都想要所以产生了协程.

3 异步和协程的关系

异步实现主要是在commit和callback两个部分。具体流程如下

对于协程来讲,在fd添加到epoll管理后,引入一个yield()原语操作让出操作,去执行其它的就绪的,在resume()恢复到现场,继续往下执行。

3 yield()和resume()原语实现方案

常见的实现方案:

a) setjmp/longjmp

b) ucontext(linux底层提供的)

c) 汇编代码实现跳转

对于第一种setjmp/longjmp实现起来比较简单在对应的位置调用api即可。

而汇编代码实现可读行更强,推荐采用第三种方式汇编实现(大部分情况下是直接用开源组件来调用即可)

两者底层都调用switch接口。

4) 协程切换

对于原语yield和resume操作底层都是通过switch(A,B)实现。以单cpu为例:来看协程切换流程:

协程A让出给B,将cpu寄存器值保存到协程A中(定义一组结构体struct context);
当切换的时候,加载协程B的数据到cpu寄存器中。
)

5) 协程创建

协程框架会提供一个接口用于创建协程,创建完成的协程添加到就绪队列,协程的入口函数通过寄存器eip将协程函数保存起来。

6) 协程的定义

协程包括:就是要封装一个协程的结构体。

context上下文,stack栈空间,协程栈大小,协程入口函数,入口参数,协程的状态集合(wait,sleep,ready),exit,status状态

状态集合:wait状态采用红黑树或者队列实现,sleep休眠可采用红黑树和最小堆实现,ready状态可采用队列实现

目录
相关文章
|
5月前
|
API 调度
2.3.1 协程设计原理与汇编实现
2.3.1 协程设计原理与汇编实现
|
2月前
|
存储 Linux 调度
协程(coroutine)的原理和使用
协程(coroutine)的原理和使用
|
14天前
|
调度 Python
揭秘Python并发编程核心:深入理解协程与异步函数的工作原理
在Python异步编程领域,协程与异步函数成为处理并发任务的关键工具。协程(微线程)比操作系统线程更轻量级,通过`async def`定义并在遇到`await`表达式时暂停执行。异步函数利用`await`实现任务间的切换。事件循环作为异步编程的核心,负责调度任务;`asyncio`库提供了事件循环的管理。Future对象则优雅地处理异步结果。掌握这些概念,可使代码更高效、简洁且易于维护。
15 1
|
20小时前
|
存储 前端开发 rax
协程设计与原理(二)
协程设计与原理(二)
7 0
|
3月前
|
调度 Python
揭秘Python并发编程核心:深入理解协程与异步函数的工作原理
【7月更文挑战第15天】Python异步编程借助协程和async/await提升并发性能,减少资源消耗。协程(async def)轻量级、用户态,便于控制。事件循环,如`asyncio.get_event_loop()`,调度任务执行。异步函数内的await关键词用于协程间切换。回调和Future对象简化异步结果处理。理解这些概念能写出高效、易维护的异步代码。
47 2
|
5月前
|
存储 关系型数据库 MySQL
纯c协程框架NtyCo实现与原理
纯c协程框架NtyCo实现与原理
136 1
|
5月前
|
存储 前端开发 rax
|
5月前
|
存储 SQL NoSQL
协程的设计原理与汇编实现
协程的设计原理与汇编实现
|
5月前
|
存储 前端开发 rax
不一样的编程方式 —— 协程(设计原理与汇编实现)
不一样的编程方式 —— 协程(设计原理与汇编实现)
|
11月前
|
存储 关系型数据库 MySQL
2.3.1 协程设计原理与汇编实现
c++的这样的内部变量还有哪些?都是什么含义? 非协程链接mysql的过程是怎样的?
35 0