Golang Go语言中协程真正的作用是什么

Golang Go语言中协程真正的作用是什么

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

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

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

这里面是都是正确的吗?

29 回复

不加场景的话 严格说都不对 协程可以提一句 降低上下文切换频次

更多关于Golang Go语言中协程真正的作用是什么的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


以前是为了充分利用 CPU 资源(在现代操作系统出现之前);
现在是为了简化异步操作,提升程序员编写代码的简洁性;

https://www.zhihu.com/question/20511233
谷歌搜到了知乎的湖大,感觉很牛,尼康康。OwO

#2 +1 切换到 go 就是为了异步处理省事好写…

感觉网上讨论“协程”更多是指有调度器的,单线程执行的协程。我自己没有接触过,并不太了解。
我自己最早接触协程是 Python 和 JavaScript 的 async fuction 和 generator,这里的协程是一种可以中途返回,后面再恢复执行的函数,现在 C++ 20 的协程也是属于这一类。
如果讨论是后面这种协程的话,那处理 IO 快不快、上下文开销大不大,完全取决于怎么实现的,用户可以用线程池+同步 IO 。

把多线程能解决的问题搞复杂,把多线程不能解决的问题解决掉

goroutine 就是减少频繁的线程上下文切换带来的 CPU 消耗吧,以及 goroutine 占用的内存空间更小。
G-P-M 模型,真正需要切换线程是在 M 的切换,G 的切换是 go 在用户态实现的调度器来做的,更像是一种用户态线程。

真正的作用,那就是处理能力分时啊。。

协程是单线程异步,你不需要处理锁的问题

goroutine 是多线程协程,能并行的,跟别的语言的单线程协程还是有很大不同的

感谢大家。

感觉协程在 JS 来说可能语法上更加方便。

我可能看了一些奇怪的文章,说协程能提升 IO 速度搞得我十分困惑。我是觉得 IO 问题是多路复用解决的。

我感觉 go 的协程可以解决一些问题,创建 1000 个线程任务的代价和创建 1000 个协程任务(可能只有几个线程)的代价是不一样的,上下文大部分情况应该都是相同的,上下文切换次数也是不一样的。

协程上下文开销很少
协程占用资源很少
这两对的
在这两个的前提下 ,才有“协程处理高并发很快”

因为携程切换都是在用户态进行,所以速度很快,而且每次切换保留现场的资源很少

我觉得解决回调地狱是最大的作用

协程处理 IO 很快

一百万 IO 任务需要处理
用线程解决,同时只能启动 1000 个
用协程解决,同时只能启动 100000 个

你猜,最后哪种解决方案先完成,先完成的解决方案,算不算快?

我觉得在这两个处理 IO 速度是一样的,Golang 里协程也是通过线程实现的,最后都要走到系统调用上,假设采取的都是同样的 IO 技术,无论到没到达系统 IO 瓶颈,速度都是一样的,甚至说,线程还能比协程快一些。以我的了解,像这种阻塞的系统调用,并发启动 100000 个协程 = 启动 启动 100000 个线程,会爆炸的。不知道是不是对的。

  1. 用协程也是有用到锁的时候
    2. 协程减少了上下文切换的时间
    3. 用起来更方便,可以控制每个协程的状态(有的实现例外)

减少线程的上下文切换。

3 是重点 用户态的切换开销小

10w 协程不可能等同于 10w 线程。
IO 堵塞的时候,线程切换的开销多大?这还没提机器,创建线程的资源大小能和协程相比么…

如果不考虑多路复用,协程会吊打线程。实际应用中,因为多路复用会导致两者差异并不是非常大。
但是如果线程与线程之间需要传输资源…差距又会被拉很大。
而且线程是比协程复杂的多的…玩的不好……就不用说了

不对,Golang 只是在有需要的时候自动开线程以充分利用 CPU,协程与线程不是一比一,而是多比一。

就是合集利用 io 等待时间来执行其他任务,让 cpu 一直处于忙的状态

说个我的看法
我觉得只需要记住一点就行了: 协程不能改善计算密集型任务的执行效率,但却能极大改善大量需要 白 白 干 等 的任务(典型就是 IO 密集)的执行效率

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

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

所以理解到这层之后,就会发现我们生活处处都是在用协程做事。然后什么情况协程比线程更好也能比较好判断了

对了,追加个 go 协程相关的,这个上面已经有人说了:

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

go 语言的协程就是后者,在协程的基础上自带调度器,会根据需求创建多个线程然后把协程分配到不同线程里运行,从而利用多个核心。写代码的人根本不用去纠结该开几个线程,每个协程该怎么调度

goroutine 又不是协程。

1.协程处理 IO 很快
协程不会让 IO 操作变快,但是可以在等待 IO 操作时执行其他协程,也就是提高了吞吐量
2.协程处理高并发很快
同 1, 吞吐量大了才能处理高并发
3.协程上下文开销很少
相较于 fork join 模式,线程池+有栈协程的开销更小,但是 Rust 的无栈协程才是无开销的模式
创建线程需要操作系统分配完整的栈+TCB, 而创建有栈协程只需要分配较小的栈+运行时自己调度,无栈协程在编译时直接变成状态机,运行时建立这个状态机就一直执行下去了,不需要分配栈.
4.协程占用资源很少
有栈协程会分配一块内存作为栈,比线程省资源

作为IT领域的GO语言专家,对于Golang中的协程有深入的理解。协程在Golang中扮演着至关重要的角色,其作用主要体现在以下几个方面:

  1. 轻量级并发:协程是Go语言的核心特性之一,它实现了轻量级的并发。与传统的线程相比,协程的创建和销毁成本非常低,这使得程序能够高效地运行大量的并发任务。
  2. 高效的资源利用:由于协程的轻量级特性,它们能够在较少的系统资源下运行,从而提高了资源的利用率。这对于处理大量并发请求或执行I/O密集型任务的应用程序尤为重要。
  3. 简化并发编程:协程使得并发编程变得更加简单和直观。开发者只需在函数调用前加上“go”关键字,即可创建一个新的协程来并发执行任务。此外,协程之间可以通过通道(Channel)进行通信,这进一步简化了并发编程的复杂性。
  4. 提高程序性能:在高并发场景下,协程能够显著提高程序的性能。它们避免了传统线程由于频繁上下文切换而产生的性能开销,从而实现了更高的吞吐量和更低的延迟。

综上所述,协程在Golang中发挥了至关重要的作用,它们使得程序能够以高效、简单和直观的方式实现并发执行。

回到顶部