猿问

Go(lang) 中的地址空间是什么?

我试图了解 Go 中并发编程的基础知识。几乎所有文章都使用术语“地址空间”,例如:“所有 goroutine 共享相同的地址空间”。这是什么意思?

我试图从 wiki 了解以下主题,但没有成功:

但是目前对我来说很难理解,因为我在内存管理和并发编程等领域的知识真的很差。有许多未知词,如段、页面、相对/绝对地址、VAS 等。

有人可以向我解释问题的基本原理吗?可能有一些有用的文章,我找不到。


人到中年有点甜
浏览 187回答 2
2回答

呼如林

Golang 规范:" go" 语句开始执行作为独立并发控制线程的函数调用,或者goroutine,在同一地址空间内。有人可以向我解释问题的基本原理吗?“地址空间”是一个通用术语,可应用于多种情况:地址空间是通过组合足够多的唯一标识限定符来创建的,以使地址明确(在特定地址空间内)Dave Cheney的演讲“让 Go 变得更快的五件事”说明了在同一进程地址空间中使用 goroutine 解决的主要问题:堆栈管理。Dave's 限定了“地址空间”,首先谈到线程:因为进程切换可以在进程执行的任何时候发生,操作系统需要存储所有这些寄存器的内容,因为它不知道当前正在使用哪些寄存器。这导致了线程的发展,线程在概念上与进程相同,但共享相同的内存空间。(所以这是关于内存的)然后 Dave 说明了进程地址空间(由进程管理的地址)内的堆栈:传统上在进程的地址空间内,堆位于内存的底部,就在程序(文本)上方并向上增长。堆栈位于虚拟地址空间的顶部,并向下增长。另请参阅“堆栈和堆是什么以及在哪里? ”。问题:因为堆和栈相互覆盖将是灾难性的,操作系统通常会安排在栈和堆之间放置一个不可写的内存区域,以确保如果它们确实发生冲突,程序将中止。对于线程,这可能会导致限制进程的堆大小:随着程序中线程数量的增加,可用地址空间的数量会减少。goroutine 使用不同的方法,同时仍然共享相同的进程地址空间:那些 goroutine 的堆栈要求呢?Go 编译器不使用保护页,而是在每个函数调用中插入检查,以检查是否有足够的堆栈供函数运行。如果没有,运行时可以分配更多的堆栈空间。由于这种检查,goroutines 的初始堆栈可以变得更小,这反过来又允许 Go 程序员将 goroutines 视为廉价资源。Go 1.3 引入了一种管理这些堆栈的新方法:如果 goroutine 的堆栈太小,将分配一个新的、更大的堆栈,而不是添加和删除额外的堆栈段。旧堆栈的内容被复制到新堆栈,然后 goroutine 继续使用新的更大的堆栈。在第一次调用 H 之后,堆栈将足够大,因此对可用堆栈空间的检查将始终成功。

HUH函数

当您的应用程序在 RAM 上运行时,RAM 中的地址由内存管理器分配给您的应用程序。这称为地址空间。概念:处理器 (CPU) 在 Fetch-Decode-Execute 循环中执行指令。它通过将指令提取到 RAM(随机存取存储器)来执行应用程序中的指令。这样做是因为从磁盘一路获取它的效率非常低。有人需要跟踪内存使用情况,因此操作系统实现了内存管理器。您的应用程序由一些程序组成,在您的情况下,这是用 Go 编程语言编写的。当您执行脚本时,操作系统以上述方式执行指令。看了你的帖子,感同身受。随着程序的增多,你提到的术语会变得越来越熟悉。我第一次从操作系统书(又名恐龙书)中遇到这些术语。希望这对你有帮助。
随时随地看视频慕课网APP

相关分类

Go
我要回答