首页 > 其他分享 >协程概述讲解

协程概述讲解

时间:2023-05-28 18:22:05浏览次数:41  
标签:异步 协程 概述 IO 讲解 线程 cpu 运行

协程

线程分为用户级线程,内核级线程和轻量级线程。Linux中使用的是轻量级线程,而协程虽然是运行在线程之上,但是是run在用户空间。并且协程和线程一样,拥有自己的调度器、cpu的上下文切换等。

协程在我个人看来是一种用户级线程;

  • 这是因为对于cpu有上下文的切换,而且是在用户空间的层次进行数据处理;一旦被内核的代码阻塞,是无法进行解除阻塞状态;

协程的功能

首先需要明确一点,协程是干嘛的,针对的事物是什么?

  • 协程针对的是IO处理,可以将多个同步关系的IO处理的性能接近于异步IO的效率;
  • 这样既保证了编写代码的逻辑,又保证了代码执行的效率;

异步IO的效率高,是正常的,因为调用某个IO函数,也就是系统调用,根据异步IO模型中的描述,它不会被阻塞且处理完毕后会通知调用线程,也就是异步IO模型没有阻塞时间

协程的做法

那么问题就来了,应该是一个什么样的逻辑处理同步IO,才能让其性能接近异步IO呢?

  • 消除同步IO被阻塞住时的等待时间,从而让效率无限接近于异步IO。
  • 这就是协程干的功能,一旦被阻塞住了,就会把cpu让出给其他可以执行的协程。

cpu切换上下文过程

协程由运行体调度器组成。

协程的运行体中保存着让出后的寄存器状态,方便于之后恢复、子过程函数和其参数、自身协程的状态、栈的大小等;

也就引出了yeild和resume这两个功能

  • yeild的中文名叫让出,cpu每个时刻只能运行一个操作(),让出操作会让当前cpu的寄存器空出给其他协程运行体(函数)使用
  • resume的中文名叫恢复,cpu空出后,恢复之前协程运行体(函数)执行的位置。

由于讨论的是一个线程的操作,不会出现内核切换线程的操作。

接下来要说是调度器,使用yeild和resume两个操作,进行切换协程。使用协程A->调度器->协程B这种形式的切换,而不是协程A->协程B。下图可以很好说明这个形式。

协程状态检测

协程调度器在调度协程运行体的时候就需要维护协程所具有的状态,比如就绪、等待、睡眠。

这也就需要一些数据结构进行维护这些运行体。

  1. 就绪状态由于这些运行体不需要设置优先级,就可以使用队列先进先出的性质;
  2. 睡眠一定会有过期时间,就可以使用定时器相关的数据结构,比如红黑树、最小堆等。
  3. 等待IO准备也是有时间的,同睡眠状态一样,使用相同的数据结构

总结

  1. 协程是针对同步IO处理的一个组件,让同步逻辑的代码有着异步的效率;
  2. 利用IO阻塞的时间,去处理其他的事情。但是你要说它是异步也不对,它的整体代码逻辑是串行的;
  3. 协程是由运行体和调度器组成;
  4. 运行在一个线程上,针对于服务器开发,不需要为每一个客户端连接的IO创建一个线程(这种方法本身就是不对的,因为有上万个客户端,不能也创建上万个线程,对吧),让这个度比使用线程更小。

扩展

至于它和reactor进行对比,它俩的性能差距不会很大。

协程相比于reactor,reactor的回调函数太过于分散,不易代码可读。

reactor其实是对事件进行一个异步的处理,于此同时也不需要看到IO处理的逻辑,只需要关注每一个事件应该怎么做。

标签:异步,协程,概述,IO,讲解,线程,cpu,运行
From: https://www.cnblogs.com/zqurgy/p/17438624.html

相关文章

  • Python asyncio之协程学习总结
    实践环境Python3.6.2什么是协程协程(Coroutine)一种电脑程序组件,该程序组件通过允许暂停和恢复任务,为非抢占式多任务生成子程序。协程也可以简单理解为协作的程序,通过协同多任务处理实现并发的函数的变种(一种可以支持中断的函数)。下面,我们通过日常生活场景为例,对什么是协程......
  • Python协程:从yield/send到yield from再到async/await
    Python中的协程大概经历了如下三个阶段:最初的生成器变形yield/send引入@asyncio.coroutine和yieldfrom在最近的Python3.5版本中引入async/await关键字一、生成器变形yield/send普通函数如果出现了yield关键字,那么该函数就不再是普通函数,而是一个生成器。importrandom......
  • 设计模式概述
    推荐文档:https://www.cnblogs.com/zhili/p/DesignPatternSummery.htmlhttps://www.runoob.com/design-pattern/design-pattern-tutorial.html为什么要使用设计模式?使用设计模式的根本原因是适应变化,为了增加代码复用率,是软件更具有维护性和可扩展性。设计原则单一职责原则......
  • JDBC概述
    1. JDBC 概述  8201.1 基本介绍1. JDBC为访问不同的数据库提供了统一的接口,为使用者屏蔽了细节问题。2. Java程序员使用JDBC,可以连接任何提供了JDBC驱动程序的数据库系统,从而完成对数据库的各种操作。3. JDBC的基本原理图[重要!]4. 模拟JDBC2. 模拟 JDBC  821代码在c......
  • 计算机及计算机软件概述
    本节课的主要内容:​计算机的基本组成部分​计算机的优势以及特点​计算机的发展趋势​计算机软件薪资待遇​学习计算机软件很难吗?需要怎么去学习?1.计算机的基本组成部分​计算机(computer)俗称电脑,是现代一种用于高速计算的电子......
  • 协程
    uContext(#include<ucontext.h>)数据结构typedefstructucontext_t{unsignedlong__ctx(uc_flags);structucontext_t*uc_link;//uc_link指向当前context结束时待恢复的上下文stack_tuc_stack;//context使用的栈初始化栈顶指......
  • 实例讲解Spring boot动态切换数据源
    摘要:本文模拟一下在主库查询订单信息查询不到的时候,切换数据源去历史库里面查询。本文分享自华为云社区《springboot动态切换数据源》,作者:小陈没烦恼。前言在公司的系统里,由于数据量较大,所以配置了多个数据源,它会根据用户所在的地区去查询那一个数据库,这样就产生了动态切换数据源......
  • 深度学习进阶篇-预训练模型[3]:XLNet、BERT、GPT,ELMO的区别优缺点,模型框架、一些Trick
    深度学习进阶篇-预训练模型[3]:XLNet、BERT、GPT,ELMO的区别优缺点,模型框架、一些Trick、TransformerEncoder等原理详细讲解1.XLNet:GeneralizedAutoregressivePretrainingforLanguageUnderstanding1.1.从AR和AE模型到XLNet模型自回归模型(AutoregressiveModel,AR),通过估计......
  • 实例讲解Spring boot动态切换数据源
    摘要:本文模拟一下在主库查询订单信息查询不到的时候,切换数据源去历史库里面查询。本文分享自华为云社区《springboot动态切换数据源》,作者:小陈没烦恼。前言在公司的系统里,由于数据量较大,所以配置了多个数据源,它会根据用户所在的地区去查询那一个数据库,这样就产生了动态切换数......
  • Pytest - Fixture(1) - 入门&概述
    Pytest-Fixture入门&概述之前讲过测试用例的前置和后置的方法,可以使用setup和teardown函数实现,但是这种方法是用于全部测试用例的;当我有部分测试用例不需要setup的方法该怎么办?pytest提供了fixture方法,让我们可以自定义测试用例的前置及后置条件;还可以根据配置......