首页 >> 大全

拥抱新技术 —— 协程

2023-08-26 大全 28 作者:考证青年

文章目录 非对称协程和对称协程独占栈和共享栈定时器参考文献

写在前面:

本文主要针对使用C/C++或有C/C++基础的读者,讨论的开源网络库libco

什么是协程

很多人描述协程为 “轻量级线程” 、 “用户态线程” 等等。之前博主对这个东西也很迷惑?

这都是啥!!!不急,博主将会写一系列文章来理清楚协程,此为系列文章的第一篇,主要介绍协程的一些基本知识:

为了理清楚协程,我们还得对线程的概念进行回忆一下:

线程是操作系统能够进行运算调度的最小单位。被包含在进程之中,是进程的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程可以并发执行多个线程,每个线程会执行不同的任务。对应在现实生活中,进程是组长,线程是小组成员。

既然说线程是系统调度的最小单位,那么又何来说协程的概念呢?通过阅读大量的文献以及之后,我对协程有了自己的看法。

下面我将一条一条来解读这些特性:

协程之于线程

刨除操作系统CPU对线程调度的因素,我们就单考虑一个线程之中的情况。

首先,协程之于线程跟线程之于进程是一样的,一个线程之中是有多个协程的。

拥抱新零售_

可以把线程想象成一个单核CPU,而协程A、B都是原来的进程。协程A、B通过一个叫协程调度器的东西来负责协程A、B的交替执行。

注:

以上情况只涉及libco 中的设计,go语言中的协程其可以运行在多个“CPU”(线程)。

在libco中,一个协程只能运行在一个线程中,这也就是说它为什么在线程中是串行的原因。因为对于一个单核CPU中,也没法进行两个进程的并行啊。

协程的切换

切成的切换得益于其在用户态就保存了栈和寄存器信息。这里面有当前协程的状态信息,有下一条执行的地址信息。这么说有点抽象,我们看一下下面的一个例子吧:

假设协程A正在执行以下函数:

void funa(void)
{int a = 10;int b = 20;sum(a,b);
}

如果说当协程A执行到sum函数的时候,协程调度器调度协程B,协程A的信息就会被保存起来。那么当前协程的的运行状态信息就是 a=10,b=20,下一条该执行的函数是sum。等待下次协程A被调度器调度,这些信息就会被恢复,再次从协程A去执行。

非对称协程和对称协程

协程目前分两种,一种是go语言采用的对称协程;一种是libco采用的非对称协程。

这里借用知乎博主tx征服者的图来向大家说明:

对称协程其实就是由协程调度器来负责,协程不允许调度其他协程。调度器协程A,那么协程A会yeild回调度器,再由调度器去执行其他的协程。如果我们把的虚线都放在左边,yeild的实线都放在右边。以调度器为中心,那么他是不是就是一个对称的图形呢?

我们再来看一下非对称协程:

拥抱新零售_

非对称调度由调度器来调度协程A,然后协程A再调动协程B。那么让出CPU使用权就不是让给调度器了,而是协程A。简而言之就是从哪儿来,回哪儿去。

同样,将此展开也不是一个对称的图形了。

独占栈和共享栈

独占栈( )即为每个协程分配一个单独的、固定大小的栈;

共享栈( the stack)则仅为当前正在运行的协程分配栈内存;

共享栈这里其实就是当协程被切出去时,就把它实际占用的栈内存copy保存到一个单独分配的缓冲区;当被切出去的协程再次调度执行时,再一次copy将原来保存的栈内存恢复到那个共享的、固定大小的栈空间。

libco将两者都实现了,默认使用前者。

定时器

为什么要介绍定时器呢?是因为定时器是协程调度中不可缺失的一个部分。就跟CPU的时间片轮转法一样,协程调度器通过定时器来调度协程。

定时器是事件驱动模型的网络框架的必不可少的功能。网络I/O的超时、定时任务,包括定时等待都依赖于此。

一般而言,使用定时功能时,我们首先向定时器中注册一个定时事件,在注册定时事件时需要指定这个事件在未来的触发事件。在到了触发时间点后,我们会收到定时器的通知。

网络中的定时器,一般可以看做两部分组成:

libco中则是直接使用epoll来定时,其中的定时器实现算法如下:

:调用等待I/O就绪事件,最大等待时长设置为1毫秒处理I/O就绪事件:循环处理得到的I/O就绪文件描述符从时间轮取超时事件:从时间轮取超时事件,放到队列处理超时事件:如果取到的超时事件不为空,那么就循环处理队列中的定时任务跳到步骤1 参考文献

[1] C++开源协程库libco详解
[2]协程学习(对称和非对称).tx征服者.知乎

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了