协程真正的作用是什么

2020-09-09 14:46:03 +08:00
 PiersSoCool

这里我想出个判断题,看看大家想的是不是一致的

相对于线程来说,假设有很多请求,假设是 Golang 语言

  1. 协程处理 IO 很快
  2. 协程处理高并发很快
  3. 协程上下文开销很少
  4. 协程占用资源很少

这里面是都是正确的吗?

6063 次点击
所在节点    Go 编程语言
28 条回复
Aoang
2020-09-09 22:11:38 +08:00
@PiersSoCool 10w 协程不可能等同于 10w 线程。
IO 堵塞的时候,线程切换的开销多大?这还没提机器,创建线程的资源大小能和协程相比么…

如果不考虑多路复用,协程会吊打线程。实际应用中,因为多路复用会导致两者差异并不是非常大。
但是如果线程与线程之间需要传输资源…差距又会被拉很大。
而且线程是比协程复杂的多的…玩的不好……就不用说了
cmdOptionKana
2020-09-09 22:19:56 +08:00
@PiersSoCool 不对,Golang 只是在有需要的时候自动开线程以充分利用 CPU,协程与线程不是一比一,而是多比一。
Acoolda
2020-09-09 23:14:33 +08:00
就是合集利用 io 等待时间来执行其他任务,让 cpu 一直处于忙的状态
hakono
2020-09-09 23:31:00 +08:00
说个我的看法
我觉得只需要记住一点就行了: 协程不能改善计算密集型任务的执行效率,但却能极大改善大量需要 白 白 干 等 的任务(典型就是 IO 密集)的执行效率

其实在这里是有一个界限的,线程数量少的时候其实用多线程还是协程差别没那么大。但是当线程非常多,切换开销过大时,协程的优点才会显现,1,2,3,4 才会大致成立(比如大量 IO 请求)

其实对人类来说,协程才是我们最熟悉、用得最多的处理事情的逻辑。不如说大部分时候我们都是在用协程的思维在处理事情的。即便是对编程一无所知的大妈,平时做饭时都在用协程思维:在烤面包的空档去切菜做其他事情,而不是烤面包的时候就在那干等面包烤完。这就是典型的协程思维。 烤面包需要好几分钟,这好几分钟是白白干等的,相当于做 IO 请求( IO 请求和 cpu 处理速度相比是非常慢的)。这 IO 请求的空档 cpu 完全能去做其他事情而不是在那干等。

所以理解到这层之后,就会发现我们生活处处都是在用协程做事。然后什么情况协程比线程更好也能比较好判断了
hakono
2020-09-09 23:31:55 +08:00
对了,追加个 go 协程相关的,这个上面已经有人说了:

讨论协程要区分一般意义上说的协程 和 go 语言的协程( goroutines )
一般意义上单线程里跑的协程是无法利用多个核心的资源的(毕竟开再多协程都是在一个线程里跑,没法利用多个核心)。解决办法就是开几个线程,把协程分配到这些线程里执行,这样就能完全利用 cpu 了

go 语言的协程就是后者,在协程的基础上自带调度器,会根据需求创建多个线程然后把协程分配到不同线程里运行,从而利用多个核心。写代码的人根本不用去纠结该开几个线程,每个协程该怎么调度
reus
2020-09-10 04:08:53 +08:00
goroutine 又不是协程。
12101111
2020-09-10 09:41:20 +08:00
1.协程处理 IO 很快
协程不会让 IO 操作变快,但是可以在等待 IO 操作时执行其他协程,也就是提高了吞吐量
2.协程处理高并发很快
同 1, 吞吐量大了才能处理高并发
3.协程上下文开销很少
相较于 fork join 模式,线程池+有栈协程的开销更小,但是 Rust 的无栈协程才是无开销的模式
创建线程需要操作系统分配完整的栈+TCB, 而创建有栈协程只需要分配较小的栈+运行时自己调度,无栈协程在编译时直接变成状态机,运行时建立这个状态机就一直执行下去了,不需要分配栈.
4.协程占用资源很少
有栈协程会分配一块内存作为栈,比线程省资源
chaleaoch
2020-09-10 14:02:50 +08:00
234 吧.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/705493

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX