前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浅谈协程

浅谈协程

原创
作者头像
windealli
修改2018-07-19 18:13:57
8220
修改2018-07-19 18:13:57
举报
文章被收录于专栏:windealli

引言

基础知识

如果了解一些操作系统的相关知识的话,我们应该知道:进程是资源分配的最小单位,线程是CPU调度的最小单位。

(这里的CPU,指的是一个CPU逻辑核。因为一台主机可能有多个CPU,一个CPU可能有多个核心,CPU可能还支持超线程。)

从进程和线程的角度而言,后台服务程序可以有四种模型: 单进程单线程模型,单进程多线程模型,多进程单线程模型,多进程多线程模型。

通常,一个传统的后台服务程序采用多进程多线程模型(至于为什么,不在本文讨论范围)。有少数几个进程,其中可能有一个master进程用来管理整个程序,一个proxy进程用来代理转发报文给其他进程,然后有一个worker进程来处理实际业务。worker进程通常是多线程的。

传统模型的缺陷

传统的多线程模型存在以下不足:

  1. 线程锁:由于进程才是资源分配的基本单位,不同线程会产生资源竞争的场景,因此需要通过线程锁来保证线程安全。锁的使用需要及其小心。
  2. 同步:不同的线程经常存在需要同步结果的场景。这可能需要借助semaphore、event、join等工具,而且可能还需要有一个线程阻塞来处理其它线程的同步结果。
  3. 性能: 多线程会产生CPU调度,CPU调度是有开销的。

简单的说就是,多线程模型在性能上不够优,而且实现的时候会有很多额外的工作量。

协程在一定程度上解决的这些问题,它基本可以实现多线程模型的效果,又不需要考虑锁、同步等问题。

协程

协程是什么

协程是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。

以下是来自wikepedia的介绍:

Coroutines are computer-program components that generalize subroutines for non-preemptive multitasking, by allowing multiple entry points for suspending and resuming execution at certain locations. 协同程序是计算机程序组件,它通过允许多个入口点在某些位置暂停和恢复执行来概括用于非抢占式多任务的子程序。

协程的实现原理

在协程中,一个线程里会有多个子程序(任务),这些子程序可以协同合作,看起来就像多个线程一样。然而,我们说线程才是CPU调度的基本单位,不进行CPU到底如何实现多任务呢,前面已经说过,是通过设置一些暂定和恢复子程序执行的入口点实现的。

协程拥有自己的寄存器上下文和栈,协程中的子程序有点类似于函数调用。但是函数调用只有一个入口,且退出后下次调用就需要从头开始执行。而协程允许在子程序的中间多个位置暂定和恢复执行。

下面利用C中的goto,实现一个简单的协程模型:

代码语言:javascript
复制
#include <stdio.h>                                                                               
 
int main()
{
    int line;
    
    {   // 子程序1
        for (int i=0; i < 10; i++) {
            goto coroutine2;
coroutine1:
            printf("coroutine 1: %d\n", i); 
        }
    }   
 
    {   //子程序2
        for (int j=0; j < 10; j++) {
            goto coroutine1; 
coroutine2:
            printf("coroutine 2: %d\n", j); 
        }
    }   
 
    return 0;
}
​

子程序1和子程序2可以像线程那样交替执行,由于两个子程序在同一个函数中,变量i和j的栈空间没有被销毁,而不需保存上下文。

也可以通过setjmp和longjmp来实现用单独函数表示子程序的协程模型。

以上只是通过模型来简单介绍协程的原理,实际应用中可能是通过汇编或其他更精妙的方式来实现协程。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
    • 基础知识
      • 传统模型的缺陷
      • 协程
        • 协程是什么
          • 协程的实现原理
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档