侧边栏壁纸
博主头像
Z同学博主等级

工作磨平激情前,坚持技术的热忱。 欢迎光临Z同学的技术小站。 分享最新的互联网知识。

  • 累计撰写 274 篇文章
  • 累计创建 55 个标签
  • 累计收到 74 条评论

协程 Coroutine

Z同学
2021-10-21 / 0 评论 / 1 点赞 / 390 阅读 / 1,431 字
温馨提示:
本文最后更新于 2021-11-18,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

前言

今天,我们来好好理解协程这个概念,现在很多新的开发语言都支持协程。

那么协程到底是什么?为什么那么多语言都要支持呢?

我们先针对这个概率有一个比较清晰的理解。才能方便我们进行学习和使用。

历史

维基百科上介绍协程(Coroutine) 是Melvin Conway在1958年创造了协程这个术语,并用于构建汇编程序。

而到了1963年,正式作为一个概念被提出发表了。

所以,协程这个概念发明的很早。

一开始是在Simula 和Modula-2等语言中出现。现在Go,goLand,Kotlin,Python等都提供了协程的相关API库。

嗯,现在java上没有协程。如果你一直接触的都是java 可能就会对协程比较陌生了。

理解

协程,也叫做微线程,它本质上就是模拟线程的实现,又不像线程那么耗费CPU资源的东西。

理解协程前,我们需要了解进程和线程。

进程很好理解,每个程序运行时,操作系统给分配的内存资源和运行空间等等就是进程。

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

简单理解就是:线程是最小的执行单元,进程是最小的管理单元

我们CPU本质上执行的就是一条条的线程。事实上CPU同时只能执行一条线程。但是通过高速的线程调度。让你看到效果,就是线程并列执行了。而多核处理器,就是能够同时执行多条线程,一个线程一个核。

总结1: 线程和进程都是操作系统先有的API然后暴露给外部进行调用。各种开发语言在封装后生成各种不同语言的线程接口和调度。

但是为什么说线程开销很大呢,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。如果线程过多,那么很快就会将分配的内存空间填满了。

然后针对这种效果,开发了协程进行优化。

协程其实就是一个单线程。所有的协程都在该线程中开辟的。

微信截图_20211021153749.png

这三个东东的关系是这样的。

特性

协程的一些特性介绍总结

  • 协程是运行在单线程中的并发程序。
  • 省去了传统线程并发机制造成的性能开销,提高了并发性能。
  • 一个线程中可以任意创建多个协程。
  • 相较于线程,安全性更高,不会造成程序无响应。

协程于线程的对比

Thread: 线程拥有独立的栈和局部变量。多线程时需要加锁来进行访问控制,否则容易导致数据错误。如果加锁过多,容易造成死锁。

线程之间的调度是由CPU控制决定的。开发人员无法介入控制。

多线程比较考验人的,就是各种调度和访问的同时避免死锁的发生,同时还要保证访问数据时的准确性。性能开销的节省。

Coroutine:协程就比较简单了。线程的多线程复杂,那么我就自己实现并发。自己决定不同协程中的挂起,暂停。彻底废弃加锁的业务逻辑。一个线程中可以创建多哥协程。同一时间只有一个协程在执行。

因为不用切换线程了,都是在一个线程中。所以协程执行效率比多线程高。

我们可以想让它在什么时候中断,什么时候启动,都可以由函数进行控制操作了。

主要追求就是为了能够更高效便捷的实现异步操作。

总结

协程是跑在线程上的,一个线程可以同时跑多个协程。

每一个协程则代表一个耗时任务,我们手动控制多个协程之间的运行、切换。决定谁什么时候挂起,什么时候运行,什么时候唤醒,而不是 Thread 那样交给系统内核来操作去竞争 CPU 时间片。

也就是说,我们可以使用协程,实现以前必须多线程才能实现的效果。在一个线程中就执行了。提高了整体的处理逻辑。

如果面临协程处理不了的。我们任然可以进行线程开销处理。

并不是说,协程替换掉了进程。而是利用协程更高效挖掘了线程的使用场景而已。

1

评论区