Golang中全局变量的工作原理解析
Golang中全局变量的工作原理解析 我在一个包中创建了一个全局变量并存储了值。
现在我创建了另一个应用程序并存储了值,在打印值之前我调用了睡眠函数10秒,然后打印它。
与此同时,我在另一个终端中再次调用了相同的应用程序,但移除了睡眠并更改了全局变量中存储的值。
但后来我发现两个应用程序都打印了我发送的值(不同的值)。但据我所知,当全局值被更改时应该会受到影响。
我不知道是我的理解有误还是Go就是这样工作的。有人能帮忙解释一下吗?
谢谢。
您也可以将此变量传递到需要它的地方,没有必要将其设为全局变量。
更多关于Golang中全局变量的工作原理解析的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
正如geosoft1所说,我需要在全局变量中存储驱动程序创建的语句句柄,并在其他函数中使用它。
既然两个应用程序运行在不同的处理器上,全局变量是不同的这一点我明白了。假设有人想要访问另一个应用程序存储的值,他能够访问到吗?
无论如何,使用全局变量都不是个好主意,你为什么需要它们呢?全局并不意味着你可以从另一个应用程序访问它,它们不共享内存。希望我理解正确了。
全局变量并不意味着在整个机器范围内都是全局的。它们在进程地址空间内才是全局的。
func main() {
fmt.Println("hello world")
}
acim:
为什么需要它们?
在某些特定情况下全局变量是有用的。我认为一些常见的场景是数据库操作或处理模板时。此外,我见过在并发编程中使用受保护的全局映射(而非通道)的情况。不过,我还没确定这是否是一种好的实践方式。
你观察到的行为是正确的,这与 Go 语言中全局变量的作用域和工作原理有关。在 Go 中,全局变量是在包级别定义的变量,但每个独立的 Go 应用程序(即每个独立的进程)都拥有自己独立的内存空间。因此,在一个进程中修改全局变量不会影响另一个进程中的全局变量值。
原理解析:
- 全局变量的作用域:在 Go 中,全局变量仅在定义它的包内可见,并且其生命周期与应用程序(进程)的生命周期相同。每个进程启动时,都会初始化自己的全局变量副本。
- 进程隔离:操作系统为每个运行的应用程序分配独立的内存空间。因此,即使两个应用程序使用相同的代码和全局变量名,它们也是完全隔离的实例,互不影响。
示例代码说明:
假设你有一个包 mypackage 定义了全局变量:
文件:mypackage/mypackage.go
package mypackage
var GlobalValue string = "initial"
然后,你创建了两个独立的应用程序(例如,两个不同的 main 包),它们都导入了 mypackage。
应用程序 1:app1.go
package main
import (
"fmt"
"time"
"mypackage"
)
func main() {
mypackage.GlobalValue = "value_from_app1"
time.Sleep(10 * time.Second) // 睡眠 10 秒
fmt.Println("App1 - GlobalValue:", mypackage.GlobalValue)
}
应用程序 2:app2.go
package main
import (
"fmt"
"mypackage"
)
func main() {
mypackage.GlobalValue = "value_from_app2"
fmt.Println("App2 - GlobalValue:", mypackage.GlobalValue)
}
运行结果:
- 如果你先运行
app1,它会在睡眠期间被挂起。然后,在另一个终端中运行app2,app2会立即输出"App2 - GlobalValue: value_from_app2"。 - 当
app1睡眠结束后,它会输出"App1 - GlobalValue: value_from_app1"。 - 两个应用程序输出不同的值,因为它们是独立的进程,各自维护
GlobalValue的副本。
总结:
Go 中的全局变量是进程级别的,不跨进程共享。如果你需要在多个进程间共享数据,可以考虑使用外部存储(如数据库、文件系统)或进程间通信(IPC)机制,例如网络套接字、共享内存或消息队列。在单个进程内,如果你有多个 goroutine,全局变量可以被共享,但需要同步机制(如互斥锁)来避免数据竞争。

