某些语言的协程机制,其作用是什么,是否会造成额外的开销

2020-08-31 09:36:30 +08:00
 maxxfire
一般情况下线程就够用了,线程也是系统的最小调度单位。
有些语言又提供了协程机制,那么在运行的时候不是还要多开一个线程(调度器或虚拟机)来调度这些协程?这不是一种资源的浪费吗。当然有些简单的协程可能直接用 siglongjmp 堆栈还原来实现了。
像传统 C/C++,直接编译机器码,直接就跑了,简单粗暴,还整什么调度器。
5985 次点击
所在节点    程序员
51 条回复
wangyanrui
2020-08-31 09:38:54 +08:00
用户线程和内核线程有 1 比 1,1 比 n,m 比 n...
从这方面入手了解一下,协程还是挺有用的
maxxfire
2020-08-31 09:41:09 +08:00
@wangyanrui 我的意思就是这样,为了实现协程无故多开线程,造成资源浪费。
des
2020-08-31 09:42:52 +08:00
这种基础问题,搜索一下很难吗
https://www.zhihu.com/question/20511233

协程最大的优势,不需要进入到内核空间
对于“直接就跑了,简单粗暴,还整什么调度器”,我觉得你需要了解下为什么需要有多线程
wangyanrui
2020-08-31 09:43:44 +08:00
@maxxfire 😂那为了实现多线程,创建了多个内核态线程,不是更浪费吗
noe132
2020-08-31 09:44:34 +08:00
因为很多 io 需要等,吞吐量要大就必须多线程。线程创建和切换都有一定的开销
协程一般都是用 event loop 调度的,一般来说有 vm 的语言协程实现起来比多线程资源开销更小
araaaa
2020-08-31 09:49:47 +08:00
写异步回调代码麻烦,从而使用协程进行阻塞变成同步命令式调用
vk42
2020-08-31 09:52:40 +08:00
@maxxfire 不知道你具体说的哪个语言,协程和“无故多开线程“没有直接联系。通用原理可以理解为用户态线程,避免普通线程切换的代价,但不同语言实现机制不同所以需要具体讨论
zengming00
2020-08-31 09:52:55 +08:00
一句话解释清楚:线程由系统强行调度,可以做到几个人同时跑,协程是自己让出 CPU,这个人跑一会那个人跑一会
Jirajine
2020-08-31 10:23:11 +08:00
misaka19000
2020-08-31 10:24:08 +08:00
因为协程的切换比线程的切换要快
linvon
2020-08-31 10:26:21 +08:00
这不是种菜,这是在楼下超市买菜。一方面大大减少买菜需要花费的时间和路费,另一反面方便快捷不需要知道怎么去菜市场
buffzty
2020-08-31 10:35:42 +08:00
你觉得自己管理内存成本和 gc 管理内存成本哪个高
Jooooooooo
2020-08-31 10:38:04 +08:00
重新学一下进程和线程的概念吧

主要分用户态的线程和内核态的线程
tabris17
2020-08-31 10:39:52 +08:00
协程和线程 /进程的主要区别是协程切换行为是用户主动进行的,而不是操作系统进行的。

不同语言的协程实现方式不同,主要分成 stackless coroutine 和 stackful coroutine,前者比后者节省内存,也能解决栈内存分配的性能损耗。但是语法丑陋
lolizeppelin
2020-08-31 10:41:22 +08:00
当然要有开销,一般的协程也有专门的调度器啊,
没调度器要写傻掉, 你总不能所有异步的地方都自己 yeid 出去吧
MrTreasure
2020-08-31 10:42:27 +08:00
go 一个协程占用的空间 4kb 并且可以动态扩容。创建一个线程的开销远大于一个协程。协程之间切换不用切换内核空间和用户空间,线程需要。

当然最方便的还是 go func 就能开启新的协程。比 java 高到不知道哪里去了
ysc3839
2020-08-31 10:49:41 +08:00
C++ 的协程是无栈协程,语言本身也没有提供调度功能,可以看作可以中途返回的函数。在遇到 co_await 的时候可以得到一个用于恢复执行的 coroutine_handle,后面要怎么继续运行,是单线程还是多线程都是由用户自己决定了。
LokiSharp
2020-08-31 10:49:50 +08:00
是这样的啊有多线程要什么协程
xylophone21
2020-08-31 10:56:03 +08:00
> 多开一个线程(调度器或虚拟机)来调度这些协程
简单的一个逻辑问题, 假设多开一个线程额外消耗 1000,每次协程切换比线程切换少消耗 10,那么管理 100 个就回本了,管理 1000 个优势就上来了。
RudyC
2020-08-31 11:04:19 +08:00
我的理解是这样的,不知道对不对:

比如说一个时间片是 10ms,你的线程本来可以执行 10ms 的代码,这段代码里你需要进行到网络 IO,所以因为 IO 问题,这个线程才执行了 1ms 就被系统调度走,结果你这个线程才执行了 1ms

如果你在线程里使用协程,因为不需要切换到内核态,那么你在用协程进行网络 IO 的同时还可以运行其它代码,这样你可以充分利用 CPU,完成这 10ms 的时间

再加上协程的资源占用不高,而且不需要切换空间,感觉这个才是重点

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

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

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

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

© 2021 V2EX