最近更新比较少,心里十分的愧疚,实在是太忙了!向各位读者说句抱歉。python
今天要讲的这个东西说实话,我也是今天才知道,一个咱们大多数人可能历来都没用过的语法,哪就是传说中的【协程 Coroutine】。git
可能你会说,携程谁不知道啊,不就是哪一个用来订机票订酒店的软件么,这有什么好学的!这样的话你就错了,此协程非彼携程,可不要傻傻分不清楚喽!github
直白地讲,进程就是应用程序的启动实例。好比咱们运行一个游戏,打开一个软件,就是开启了一个进程,进程拥有代码和打开的文件资源、数据资源、独立的内存空间。编程
线程从属于进程,是程序的实际执行者。一个进程至少包含一个主线程,也能够有更多的子线程,线程拥有本身的栈空间。微信
线程具备五种状态:多线程
对操做系统来讲,线程是最小的执行单元,进程是最小的资源管理单元。架构
不管进程仍是线程,都是由操做系统所管理的。并发
线程之间是如何进行协做的呢?框架
最经典的例子就是生产者/消费者模式:异步
若干个生产者线程向队列中写入数据,若干个消费者线程从队列中消费数据。
官方定义以下:
A coroutine is a function that can suspend its execution (yield) until the given given YieldInstruction finishes.
用我蹩脚的英语来翻译一下就是:
学过计算机组成原理的都知道,当 CPU 在多个进程间切换时,那些后台程序就会处于这种暂停用英文的 Suspend 或许更恰当)的状态,因此早年的电脑即便用一个 CPU 也能够同时处理多个进程任务,这是一种“伪多线程”的技术。
除此以外比较重要的一点是,协程不是被操做系统内核所管理,而彻底是由程序所控制(也就是在用户态执行)。这样带来的好处就是性能获得了很大的提高,不会像线程那样须要上下文切换来消耗资源,所以协程的开销远远小于线程的开销。
注意,这里要划一个重点,协程是一种“伪多线程”,始终记得这一点,能够帮助咱们来理解协程会这个概念。
Java 语言并无对协程提供原生支持,因此用 Java 暂时还演示不了,可是有个开源框架基本模拟除了协程的功能,感兴趣的朋友能够去看看源码。。。
地址 :https://github.com/kilim/kilim
Go 语言根据我查询资料来看,对于协程的支持超乎个人想象,能够说是强大而简洁,轻轻松松分分钟建立成百上千个协程并发执行。
func Add(x, y int) {
z := x + y
fmt.Println(z)
}
func main() {
for i:=0; i<10; i++ {
go Add(i, i)
}
}复制代码
如上代码,在一个函数调用前加上 go 关键字,此次调用就会在一个新的协程中并发执行。当被调用的函数返回时,这个协程也自动结束。须要注意的是,若是这个函数有返回值,那么这个返回值会被丢弃。
Python 语言也能够经过 yield/send 的方式实现协程。在 python 3.5 之后,async/await 成为了更好的替代方案。
def consume():
while True:
# consumer 协程等待接收数据
number = yield
print("开始消费",number)
consumer = consume()
# 让初始化状态的 consumer 协程先执行起来,在 yield 处中止
next(consumer)
for num in range(0,100)
print("开始生产",num)
# 发送数据给 consumer 协程
consumer.send(num)复制代码
其余语言的写法我也就不写了,毕竟不太熟,写了怕误人子弟!!!
根据今天查阅的资料来看,协程的应用场景主要在于 :I/O 密集型任务。
这一点与多线程有些相似,但协程调用是在一个线程内进行的,是单线程,切换的开销小,所以效率上略高于多线程。当程序在执行 I/O 时操做时,CPU 是空闲的,此时能够充分利用 CPU 的时间片来处理其余任务。在单线程中,一个函数调用,通常是从函数的第一行代码开始执行,结束于 return 语句、异常或者函数执行(也能够认为是隐式地返回了 None )。 有了协程,咱们在函数的执行过程当中,若是遇到了耗时的 I/O 操做,函数能够临时让出控制权,让 CPU 执行其余函数,等 I/O 操做执行完毕之后再收回控制权。
简单来说协程的好处:
缺点:
最后再贴个图来总结一下,更清楚:
本文首发于微信公众号 【程序猿杂货铺】,关注公众号,获取更多精彩文章!