golang 是单进程的吗?

2023-10-17 13:55:56 +08:00
 chaleaochexist

我在一个 goroutine 修改环境变量, 想在其他所有 goroutine 中生效? 可以吗?

5882 次点击
所在节点    Go 编程语言
85 条回复
mightybruce
2023-10-17 16:26:12 +08:00
多个 goroutine 并不对应多进程,除非你通过 syscall 在代码主动去创建进程。
你改了环境变量,其他 goroutine 是感知不到的, 除非再次主动去读。
多个 goroutine 在一个进程中。
e7
2023-10-17 16:35:36 +08:00
以前找工作的时候经常遇到面试官问类似这种问题,一脸懵逼
awalkingman
2023-10-17 16:39:03 +08:00
你是不是想问不同 goroutine 之间的通信机制?
bler
2023-10-17 16:39:05 +08:00
我大概明白楼主是啥意思,楼主应该是想问,main1.go 和 main2.go 独立运行,会不会被 go 语言分配到同一个进程之中。我被 python 的 scrapy 框架坑过,scrapy crawl 命令运行爬虫的时候,scrapy crawl spider1 和 scrapy crawl spider2 是运行在同一个进程之下的,pipeline 的类变量在两个爬虫中会共用,估计楼主应该是遇到类似的问题了
xdeng
2023-10-17 16:39:44 +08:00
单进程是常态吧
xsen
2023-10-17 16:43:20 +08:00
@chaleaochexist #39 关键字:资源并发访问
不同进程,系统也有机制可以多进程同步
不同线程,线程同步
不同协程,对于 go 来说就是加锁如 mutex
Immortan
2023-10-17 16:49:03 +08:00
- Golang 不是单进程的,GOMAXPROCS 默认等于运行时机器的 runtime.NumCPU()
- 但是开发者不用关心,这是 OS 层面的抽象,OS 会保证即使实际运行在多核上,其行为也和运行在单核上一样,比如环境变量的变化。
- 环境变量是 OS 管理的,读取、修改环境变量都需要通过系统调用进入内核态,自然会在所有 goroutine 中生效。
- 一般非常少会通过环境变量的运行时改变来控制代码行为,尤其像 Golang 这种原生对并发支持力度就很大的语言。如上所述,环境变量的读取需要通过系统调用,某种程度上是个"很贵"的操作。
wOuv7i4e7XxsSOR1
2023-10-17 16:49:55 +08:00
这个问题槽点太多,不知道该怎么回答
LindsayZhou
2023-10-17 16:51:09 +08:00
是不是可以这样想,goroutine 之间是可以共享全局变量的,那么表示所有的 goroutine 是共用一套内存地址空间的。

而环境变量存储的位置,如果我没记错,是在程序入口前面一小段的内存里面,既然所有的内存空间是共享的,那么这段环境变量的内存也是共享的。

这样就摆脱了线程进程的概念,不用考虑那些了。

(如果是进程,那内存页就是 COW 了)
ygtq
2023-10-17 16:53:42 +08:00
@chaleaochexist 多 goroutine 是否在同一个进程下? 我的理解是,肯定在。因为你没有主动 fork ,golang 也不会主动多开一个进程,go 只是一个静态编程语言,换言之你用 c/c++写,编译生成可执行程序,代码不主动开进程,语言不会开的啊
kiripeng
2023-10-17 16:58:32 +08:00
Happens-Before 原则
EspoirBao
2023-10-17 17:04:20 +08:00
看到单进程的时候突然小脑猥琐了一下,在想是什么情况下需要改多进程的环境变量,进程一般都属于 OS 级别控制的吧???
huangzhiyia
2023-10-17 17:31:25 +08:00
不管什么语言,只要不 fork 就是天王老子来了都是单进程。要多进程,只要不主动加锁限制,都可以多进程运行(系统限制除外)
standchan
2023-10-17 17:51:35 +08:00
你没 exec 操作,goroutine 就是一定是单进程,然后 goroutine 是在语言层面复用 os 的线程。此外,我写了 demo 代码,结果是其他 goroutine 也可以读到新修改的环境变量,前提的实时去读。
RedisMasterNode
2023-10-17 18:05:09 +08:00
@dw2693734d 楼主问这个问题肯定是有他背景,例如 Python 进程经常用 Gunicorn 或者 uwsgi 托管,这些都会导致应用程序以多个进程形式运行。

我觉得大家回答不用太过抠字眼了...其实就是个快问快答,但是较真(较真不代表不好)的人很多,才搞得帖子这样...

包括一些什么可以 os.Exec 扩展多进程,拜托,别的语言一样可以,补充这种信息对回答问题一点帮助都没有,不如直接点明 Go 和其他语言的区别在哪里简洁明了。
ding2dong
2023-10-17 18:21:37 +08:00
当然可以啊,goroutine 是线程不是进程
aisk
2023-10-17 19:03:19 +08:00
@RedisMasterNode 他背景他说了,一个 goroutine 里设置环境变量另外一个读不到,然后不怀疑自己代码有 bug ,怀疑 go 是多进程运行不同 goroutine 。
chaleaochexist
2023-10-17 21:00:54 +08:00
@aisk 不是怀疑 我还没开始写呢.
提前做点调查.
chaleaochexist
2023-10-17 21:04:06 +08:00
@standchan 这个东西不能通过 demo 去验证.
当然了严谨一点说 可以证伪. 但是不能验证正确.

譬如 runtime 有一种机制, 当 goroutine < 5. 或者换个说法 count(runtime) < 5 是单进程, >=5 是多进程模式.
所以我发帖上来问问, 不知道为什么楼上一堆冷嘲热讽.
chaleaochexist
2023-10-17 21:04:56 +08:00
@standchan
count(runtime) < 5
-->
count(goroutine) < 5

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

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

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

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

© 2021 V2EX