一、相关概念
1. 进程
进程是一个实体,一个用户程序就是一个进程。
2. 线程
- 每个线程都有各自的调用栈,寄存器环境,线程本地存储。
- 线程是进程的执行体,拥有一个执行入口,以及从进程虚拟地址空间分配的栈信息,包括用户栈和内核栈。
3. 子程序
子程序又被称为执行体、函数、方法等。子程序在主程序中被调用执行。
二、协程
1. 协程的产生
- 如果线程各自创建几个执行体,给他们各自指定执行入口,申请一些内存分配给他们做执行栈,那么线程就可以按需调度这几个执行体了。
- 为了实现这几个执行体的切换,线程也需要记录执行体的信息,包括ID、栈的位置、执行入口地址、执行现场等。
- 线程可以选择一个执行体来执行,此时CPU中指令指针就会指向这个执行体的执行入口,栈基和栈指针寄存器也会指向线程给他分配的执行栈。
- 要切换执行体时,需要先保存当前执行体的执行现场,然后切换到另一个执行体,通过同样的方式可以恢复到之前的执行体,这样就可以从上次执行中断的地方继续执行。
- 这些由线程创建的执行体就叫做“协程”,因为用户程序不能操作内核空间,所以只能给协程分配用户栈,而操作系统对协程一无所知,所以协程又被称为“用户态线程”。
2. 协程的定义
-
协程(Coroutine),是一种比线程更加轻量级的存在。正如一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程。
-
协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。
引用Donald Knuth的一句话总结协程的特点:“子程序就是协程的一种特例。” 注意:在一个子程序中中断,去执行其他子程序,不是函数调用,有点类似CPU的中断。
子程序调用总是一个入口,一次返回,调用顺序是明确的。而协程的调用和子程序不同。
比如子程序A、B:
def A():
print '1'
print '2'
print '3'
def B():
print 'x'
print 'y'
print 'z'
假设由协程执行,在执行A的过程中,可以随时中断,去执行B,B也可能在执行过程中中断再去执行A,结果可能是:
1
2
x
y
3
z
但是在A中是没有调用B的,所以协程的调用比函数调用理解起来要难一些。
看起来A、B的执行有点像多线程,但协程的特点在于是一个线程执行,那和多线程比,协程有何优势?
最大的优势就是协程极高的执行效率。因为子程序切换不是线程切换,而是由程序

最低0.47元/天 解锁文章
3668

被折叠的 条评论
为什么被折叠?



