我尝试理解Go中并发编程的基础知识。几乎所有文章都使用术语"地址空间" ,例如:"所有goroutines共享相同的地址空间" 。这是什么意思?
我试图从维基中了解以下主题,但它并没有成功:
但目前我很难理解,因为我在内存管理和并发编程等方面的知识非常差。有许多未知的单词,如段,页面,相对/绝对地址,VAS等。
有人可以向我解释问题的基础吗?可能有一些有用的文章,我无法找到。
答案 0 :(得分:13)
A"
go
"语句开始执行函数调用作为独立的并发控制线程,或goroutine
中的{{1}},。有人可以向我解释问题的基础吗?
"地址空间"是一个通用术语,可以适用于许多情境:
通过组合足够的唯一标识限定符来创建地址空间,以使地址明确(在特定地址空间内)
address space的演讲" Dave Cheney"说明了在同一进程地址空间中使用goroutine解决的主要问题:Five things that make Go fast。
戴夫有资格获得#34;地址空间",首先说话:
由于进程切换可以在进程执行的任何时刻发生,操作系统需要存储所有这些寄存器的内容,因为它不知道当前正在使用哪些寄存器。
这导致线程的开发,这在概念上与进程相同,但共享相同的内存空间。
(所以这是关于记忆的)
然后Dave说明了进程地址空间中的堆栈(进程管理的地址):
传统上在流程的地址空间内,
- 堆位于内存的底部,位于程序(文本)的上方并且向上增长。
- 堆栈位于虚拟地址空间的顶部,并向下扩展。
另见" stack management"。
问题:
因为堆和堆栈互相覆盖会是灾难性的,操作系统通常会安排在堆栈和堆之间放置一个不可写内存区域,以确保如果碰撞,程序将中止。
使用线程可能会限制进程的堆大小:
随着程序中线程数的增加,可用地址空间量会减少。
goroutine使用不同的方法,同时仍然共享相同的进程地址空间:
那些goroutines的堆栈要求怎么样?
Go编译器不是使用保护页,而是在每个函数调用的一部分插入一个检查,以检查是否有足够的堆栈来运行该函数。如果没有,运行时可以分配更多的堆栈空间。
由于这个检查,goroutines初始堆栈可以变得更小,这反过来允许Go程序员将goroutines视为廉价资源。
Go 1.3引入了一种管理这些堆栈的新方法:
如果goroutine的堆栈太小,则不会添加和删除其他堆栈段,而是分配一个新的更大的堆栈。
将旧堆栈的内容复制到新堆栈,然后goroutine继续使用其新的更大堆栈。
在第一次调用H之后,堆栈将足够大,以便检查可用堆栈空间将始终成功。
答案 1 :(得分:3)
当应用程序在RAM上运行时,RAM中的地址由内存管理器分配给您的应用程序。这被称为地址空间。
处理器(CPU)执行Fetch-Decode-Execute中的指令 周期。它通过获取应用程序来执行应用程序中的指令 RAM(随机存取存储器)。这样做是因为它非常 无效率从磁盘获取它。有人需要保留 跟踪内存使用情况,以便操作系统实现内存 经理。您的申请,包括一些程序,在您的情况下 是用Go编程语言编写的。执行脚本时 操作系统以上述方式执行指令。
阅读你的帖子我可以同情。你提到的术语越来越多地为你所熟悉。
我第一次在操作系统书籍中遇到过这些术语,a.k.a恐龙书。
希望这会对你有所帮助。