几个关于 Go Runtime 的问题

2021-02-04 22:59:30 +08:00
 Dongxiem

问题:go 的 runtime 如何实现?(这个实在不理解)

追问:runtime 这个进程是运行在哪儿的?

追问:每个 go 进程都会有一个吗还是共用一个?(应该是共用一个)

追问:如果你运行了 go 进程,在 linux 系统里查看进程能看到 runtime 进程吗?

4697 次点击
所在节点    Go 编程语言
60 条回复
love2020
2021-02-05 15:28:16 +08:00
@lewis89 我要进群,qq 吗?
love2020
2021-02-05 15:28:55 +08:00
@lewis89 看到了深不可测的技术 ( ps:我要进群)
lewis89
2021-02-05 15:34:26 +08:00
@love2020 #42 没有什么深不可测的.. 你如果去读一下 linux 0.12 的代码 基本上都懂了.. 微信群..
henglinli
2021-02-05 15:47:31 +08:00
@Dongxiem 不是。
runtime 其实是 runtime dependence 运行时依赖。
你写了一个空的 main.main 函数,编译器套件隐式链接的那一部分就是 runtime,恰好这一部分也是 runtime 包。
在函数层面上,runtime 包里面的函数都是 runtime ;在操作系统层面上,你看到的 go 程序执行的线程都是 runtime 包里面的函数通过系统调用创建的。
你写的代码只是被 runtime.mian 调用而已,当你编译链接出一个 golang 编写的程序,runtime 包被隐式的链接进去,不需要你在代码里 import,因为所以的其他代码都依赖 runtime 包。

我说不好回答时,既要考虑你想要问什么,又要考虑我知道什么,还要考虑篇幅等。程序没有进内存前只是函数,你问“运行”当然是进内存后了,这些 runtime 函数都被 OS 线程调用执行,所以我回到 runtime 跑在 OS 线程上。但是有可能,你是想问 runtime 是在哪里调用的。不是你的函数调用 runtime,而是 runtime 调用你的函数,先执行 runtime,runtime 系统调用创建 OS 线程后,再调用 main.main 中你的函数。

gccgo 的 runtime 另当别论。
byte10
2021-02-05 15:52:42 +08:00
@1011 有啥优雅,又不能创建线程,死坑货 go 。我都明知道这行代码是阻塞的,它就是不让我创建线程跑,在协程跑,浪费时间。
janxin
2021-02-05 15:54:01 +08:00
这面试官以前用 Java 的?....
qieqie
2021-02-05 15:57:03 +08:00
明明主楼问的 runtime,歪到并发模型还能歪这么多楼。这里就是 i 知乎吗,i 了 i 了。
kksco
2021-02-05 16:59:05 +08:00
@lewis89 wx: MTMxNzM2ODAwMTg=
saberlong
2021-02-05 18:15:03 +08:00
@byte10 runtime.LockOSThread()
Dongxiem
2021-02-05 19:18:30 +08:00
@lewis89 谢谢大佬的回答~
Dongxiem
2021-02-05 19:19:10 +08:00
@henglinli 我觉得你回答的很符合问题了,谢谢大佬。
Dongxiem
2021-02-05 19:22:01 +08:00
@weiwenhao 是的,认识到了,理解来说就是一个库。
lewis89
2021-02-05 19:42:23 +08:00
@byte10 #45 为什么要创建线程,而且使用读写磁盘文件这种阻塞式 IO 的话,goroutine 封装了 syscall,会自动分离 M 跟 G,自动创建线程去应付这种阻塞式 IO,不比你手动去创建线程强 100 倍?
lewis89
2021-02-05 19:49:55 +08:00
@qieqie #47

i 就 i 了吧,每个人对 runtime 这个概念理解完全不一样,但是我们一般网上交流 runtime 无非是讨论 程序语言编译后的二进制文件在运行时提供的方方面面的功能,例如 程序的栈幁 调度模式(抢占 /非抢占) 调度单位 调度策略 内存回收策略 变量的生命周期 语言元信息的反射功能, 这都算作语言的 runtime,我不知道你所说的 runtime 是什么 runtime
lewis89
2021-02-05 20:01:55 +08:00
@qieqie #47 可能你有一个更好的对 runtime 的解释,愿听其详吧..
lewis89
2021-02-05 20:12:55 +08:00
@byte10 #45 另外后面的版本,即使你写了个死循环,现在 go 调度器也可以基于信号机制来实现抢占调度了
kksco
2021-02-05 20:27:44 +08:00
@lewis89 老哥,wx: MTMxNzM2ODAwMTg=
byte10
2021-02-18 08:50:16 +08:00
@lewis89 我知道有 go 是封装了所有的 IO,但是你调用一些本地函数,如第三方 so 库之类的,它们内部的读写文件和网络请求还是阻塞的。它是遇到了阻塞之后,会切换任务到其他线程中,如果所有的线程都阻塞才会启动新线程。这部分的逻辑是有性能消耗的,我明明知道一个操作是阻塞的,我手动创建线程去执行,就避免其他的运行任务队列的线程阻塞
byte10
2021-02-18 08:51:22 +08:00
@saberlong 好的,感谢
@lewis89 你可以了解下
love2020
2021-03-02 08:39:46 +08:00
@lewis89 我想加一下微信群 wx: R29waGVyLTE5OTU=

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

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

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

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

© 2021 V2EX