有没有哪里能通俗易懂地讲明白 Go 的并发?

2021-02-05 20:07:04 +08:00
 zhoudaiyu

什么 channel mutex 看的脑袋都蒙了,谁说 go 并发容易了😂

2970 次点击
所在节点    Go 编程语言
17 条回复
rrfeng
2021-02-05 20:14:01 +08:00
你先说哪里不动
lewis89
2021-02-05 20:17:26 +08:00
没有什么办法可以让你通俗易懂,真的,能写 go 调度器的人 至少得会以下几个技能

各平台的汇编以及栈幁结构(不然你真不知道协程调度是如何完成上下文切换的 以及如何实现动态栈伸缩)
操作系统信号机制 (不然你真的不知道如何实现抢断式调度)
monitor 锁 (不然你真的不知道多线程如何通信 如何同步)
调度算法 (不然你真的不知道如何调度)

建议还是老老实实先读 CSAPP 现代操作系统原理 这两本书
lewis89
2021-02-05 20:18:20 +08:00
@lewis89 #2

还有 Linux 常见的 IO 模型 以及多路 IO 复用技术
zhoudaiyu
2021-02-05 20:21:31 +08:00
@rrfeng 看烦了主要是
zhoudaiyu
2021-02-05 20:22:24 +08:00
@lewis89 主要是协程这块弄懂了就行了
shoaly
2021-02-05 20:24:18 +08:00
不是 go 的问题, 而是并发本身的模型 老哥要理解 ..
不然你随便看那个预言的线程, 或者协程都吃力...
lewis89
2021-02-05 20:24:20 +08:00
如果你没有听说过 syscall rsp rbp ip fastcall ABI 信号中断 多路 IO 复用 stackfull 这些概念或者名词 还是老老实实打基础吧..

打好了自然就明白了 ,能写的 go 的人 牛逼之处不是他用 go 语言编程有厉害,而在于能写 go 的这个人对计算机体系结构有多深刻的认识..
lewis89
2021-02-05 20:26:11 +08:00
@zhoudaiyu #5 你要弄懂协程 自然要弄懂 如何上下文切换.. 深入到细节 就又回到计算机体系结构了,又让你回到最底层了,因为一个很简单的问题,为什么要用协程,我们有好好的线程模型不用.. 你要解释这个 没点基础功夫 是不行的
lewis89
2021-02-05 20:28:13 +08:00
@zhoudaiyu #5 你要完全弄懂,自己用 C 语言手动实现一个协程,然后配合 epoll 多路复用 就能明白 goroutine 了
zhoudaiyu
2021-02-05 20:34:38 +08:00
@lewis89 估计重学要 1 、2 年才行。。不过我确实非常非常想把基础弄牢固,就是一直没找到很好的切入点,怕半途而废
misaka19000
2021-02-05 20:52:26 +08:00
Dongxiem
2021-02-07 00:52:37 +08:00
按照楼主这条问题,楼主应该多了解一些计算机底层的知识、操作系统等内容,因为高级语言都有共性的,深入理解的话还是要回到前面的内容。
Dongxiem
2021-02-07 00:54:54 +08:00
@Dongxiem 这里有一个推荐,图解形式讲解计算机内容和 Golang 的知识,可以搜索:幼麟实验室。
baiyi
2021-02-07 11:37:28 +08:00
如果只是想了解 golang 的并发而不是想看源码学习调度器的话,可以看看 Rob Pike 的演讲:《 Go Concurrency Patterns 》 <amp-youtube data-videoid="f6kdp27TYZs" layout="responsive" width="480" height="270"></amp-youtube>同样是 Rob Pike 的讲并发和并行区别的演讲:《 Concurrency is not Parallelism 》
这篇博客的配图很好:《 Visualizing Concurrency in Go 》 https://divan.dev/posts/go_concurrency_visualize/

如果是想看调度器部分源码,深刻了解 golang 的 goroutine,我推荐《 Go: Under The Hood 》,虽然欧神还没写完整本,但调度器部分已经很完善了。https://github.com/golang-design/under-the-hood
zhoudaiyu
2021-02-07 12:52:25 +08:00
@baiyi 最后一个太棒了吧,你们都是怎么找到这种资源的啊
baiyi
2021-02-07 13:16:03 +08:00
@zhoudaiyu #15 Google 搜啊,找到相关的文章就进去看,碰到不懂的知识点就再搜下一个知识点。

我当时对 go 的并发感兴趣,所以入的坑,看了一个多月的并发、调度器相关的内容。中文的 go 调度器相关的资料挺多的,但都是鹦鹉学舌,翻来覆去就是 GMP 这点东西,没几个深入的。幸好最后找到了欧神的书,虽然当时我看的时候还有些小瑕疵,但看的特别顺畅,调度器部分从头到尾的逻辑特别顺,他博客里说这叫线性写作。

如果你对这方面感兴趣,我的建议就是先看看 RobPike 的演讲,听听他们设计 Go 语言的时候是如何思考并发的。然后就跟着书看下去就行了。
xkeyideal
2021-02-07 16:13:59 +08:00
mutex 是用来解决竞争防止死锁的,任何语言都一样,没有什么套路
Go 的并发指的的 goroutine,而并发之间的通信才用的是 channel
如果协程之间不需要数据通信,那么就不需要使用 channel,这种代码入门级别的时候随便写,高阶的时候注意 goroutine 泄漏即可,但不使用 channel 的协程基本不存在
goroutine+channel 的组合才是 Go 完整的并发,其实就是一个生产者消费者模型,Go 又限制的必须先有消费者才能运行生产者,否则阻塞性 channel 会报错,非阻塞性没事
而用来控制 goroutine 的泄漏的方法一般有两种方式:context 与 channel+sync.WaitGroup,现在推荐使用 context,但个人还是喜欢用后者
另:Go 的并发确实很容易,指的是入门,但想写好,没有 goroutine 泄漏,不发生死锁,从容的控制 goroutine 的执行这个就要求就比较高了,遇到有些复杂的业务逻辑,还要会设计整个并发的流程配合一些奇技淫巧提高执行效率,那么这个就在于各种基本功了,与语言没有什么太大关系了

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

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

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

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

© 2021 V2EX