龙空技术网

什么是协程?

阿粥有话说 35

前言:

现时朋友们对“协程是单线程吗”大体比较关怀,我们都需要学习一些“协程是单线程吗”的相关内容。那么小编也在网上收集了一些对于“协程是单线程吗””的相关内容,希望朋友们能喜欢,咱们一起来了解一下吧!

最近更新比较少,内心十分的愧疚,实在是太忙了!向各位读者说句抱歉。

今天要讲的这个东西说实话,我也是今天才知道,一个我们大多数人可能从来都没用过的语法,哪就是传说中的【协程 Coroutine】。

可能你会说,携程谁不知道啊,不就是哪个用来订机票订酒店的软件么,这有什么好学的!这样的话你就错了,此协程非彼携程,可不要傻傻分不清楚喽!

什么是进程和线程

进程是什么

直白地讲,进程就是应用程序的启动实例。比如我们运行一个游戏,打开一个软件,就是开启了一个进程,进程拥有代码和打开的文件资源、数据资源、独立的内存空间。

线程又是什么

线程从属于进程,是程序的实际执行者。一个进程至少包含一个主线程,也可以有更多的子线程,线程拥有自己的栈空间。

线程具有五种状态:

对操作系统来说,线程是最小的执行单元,进程是最小的资源管理单元。

无论进程还是线程,都是由操作系统所管理的。

进程和线程的痛点

线程之间是如何进行协作的呢?

最经典的例子就是生产者/消费者模式:

若干个生产者线程向队列中写入数据,若干个消费者线程从队列中消费数据。

什么是协程

官方定义如下:

A coroutine is a function that can suspend its execution (yield) until the given given YieldInstruction finishes.

用我蹩脚的英语来翻译一下就是:

学过计算机组成原理的都知道,当 CPU 在多个进程间切换时,那些后台程序就会处于这种暂停用英文的 Suspend 或许更恰当)的状态,所以早年的电脑即使用一个 CPU 也可以同时处理多个进程任务,这是一种“伪多线程”的技术。

除此之外比较重要的一点是,协程不是被操作系统内核所管理,而完全是由程序所控制(也就是在用户态执行)。这样带来的好处就是性能得到了很大的提升,不会像线程那样需要上下文切换来消耗资源,因此协程的开销远远小于线程的开销。

注意,这里要划一个重点,协程是一种“伪多线程”,始终记得这一点,可以帮助我们来理解协程会这个概念。

协程函数的写法

Java 语言并没有对协程提供原生支持,所以用 Java 暂时还演示不了,但是有个开源框架基本模拟除了协程的功能,感兴趣的朋友可以去看看源码。。。

地址 :

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 操作执行完毕以后再收回控制权。

简单来讲协程的好处:

跨平台跨体系架构无需线程上下文切换的开销无需原子操作锁定及同步的开销方便切换控制流,简化编程模型高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题。所以很适合用于高并发处理。

缺点:

无法利用多核资源:协程的本质是个单线程,它不能同时将 单个CPU 的多个核用上,协程需要和进程配合才能运行在多CPU上.当然我们日常所编写的绝大部分应用都没有这个必要,除非是cpu密集型应用。进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序:这一点和事件驱动一样,可以使用异步IO操作来解决

最后再贴个图来总结一下,更清楚:

本文首发于微信公众号 【程序猿杂货铺】,关注公众号,获取更多精彩文章!

标签: #协程是单线程吗