zoukankan      html  css  js  c++  java
  • 谈谈协程

    谈谈协程

    关于协程,网上能看到很多资料。这里再自个梳理一下。

    协程展开来说,叫做协作的程序,想表达的意思是,两段程序,能协作地,共用公共资源,来完成两段程序各自的目的,就叫做协程了。

    把现在所有的容易混淆的名字罗列出来:并发,并行,进程,线程,协程。说说他们的历史。

    并发

    首先是并发,并发的概念是很早就有的了。最早的时候机器都是批处理系统,而且是单道批处理系统,这个系统就是很简单的线性逻辑,一个批处理任务进去,完成,然后进行下面一个。但是随着批处理的任务越来越多,我们希望的是能一次性预存很多批处理任务进入内存,然后通过一定的处理规则指定(作业调度算法)来让这些批处理任务划分CPU的时间,这样CPU的状态就像是第一秒执行A任务,第二秒执行B任务,这样看起来,A任务和B任务就像是同时在进行。这个模式,就叫做并发了。

    进程

    能并发处理多任务的系统就是多道程序系统。但是有个问题是,CPU在多个批处理任务切换的过程中,对于共享变量,堆栈都需要不断地变化和切换。那么这个时候,就引入了进程的概念,进程就是CPU处理的基本单元。每个进程有自己的上下文,堆栈,共享变量。就像一个盒子,把每个批处理任务和对应的资源都分割开了。

    并行

    下面,随着CPU硬件技术的发展,一台机器上CPU的数量就不止一个了,那么这个时候,两个CPU就可以同时,单独处理两个进程了。注意,这个同时才是真正的同时,那么这个模式,就叫做并行。

    线程

    线程的概念出现,是由于进程之前的切换需要消耗的资源太多了,很多时候,我们程序的性能都消耗在进程资源切换上了,所以我们希望的是,能不能将进程切换过程中的资源减少?这里需要深入到进程的切换,进程控制块(PCB)是系统为了管理进程设置的一个专门的数据结构,进程切换的时候,把旧的进程的状态存入到PCB,然后再加载装入新的进程的PCB。PCB里面的信息包含有:程序计数器,寄存器,变量,进程资源等信息。进程之间的切换需要把这些都进行上下文切换,最麻烦耗时的就是切换页表了,页表中存储的是数据段和代码段。这里就需要线程的概念,一个进程中有多个线程,同一个进程中的线程共用代码资源,数据资源,内存资源。所以当同一个进程中的线程进行切换的时候,我们只需要切换计数器,寄存器,变量,并不需要进行切换页表操作,这样,基本创建一个线程比创建一个进程速度要快10-100倍。

    不管是进程切换还是线程切换,我们都需要从系统调用开始,即切换必须涉及到用户态和内核态的函数调用。那么,就有人思考,我们是不是可以自己实现一个调度逻辑,让线程的逻辑切换只在用户态进行呢?这样,线程的切换开销就更小了,这个就是用户态线程。

    协程

    下面就说到协程了。不管是怎么个做法,调度算法对于程序来说都是“被动”式的。难免会遇到这种情况,我们的程序还在IO等待中,结果调度算法把CPU的时间还分配回来给我,虽然我可以通过调度算法立即检查并交出CPU,但是这里还是有一个切换的过程。所以就有人思考,是不是可以做成“主动式”的呢?由程序来告诉计算机,我执行到这里了,下面进行等待IO行为了,这个时候就把CPU的控制权交给别人吧。但是,这个实现的基础当然是调度算法是用户态的。所以,协程就是在用户态线程中,两个程序协商好了,通过某种方式协作运营,共享CPU控制权的方法。

    一般来说,这个协商的方法通用的关键字就是yield。

  • 相关阅读:
    UVA 10617 Again Palindrome
    UVA 10154 Weights and Measures
    UVA 10201 Adventures in Moving Part IV
    UVA 10313 Pay the Price
    UVA 10271 Chopsticks
    Restore DB後設置指引 for maximo
    每行SQL語句加go換行
    种服务器角色所拥有的权限
    Framework X support IPV6?
    模擬DeadLock
  • 原文地址:https://www.cnblogs.com/yjf512/p/5593181.html
Copyright © 2011-2022 走看看