【发布时间】:2017-05-10 09:28:45
【问题描述】:
今天我的一个朋友告诉我,Go 程序可以在多个 CPU 内核上扩展自己。得知系统任务调度程序对 goroutine 一无所知,因此无法在多个内核上运行它们,我感到非常惊讶。
我做了一些搜索,发现 Go 程序可以生成多个操作系统任务以在不同的内核上运行它们(数量由 GOMAXPROCS 环境变量控制)。但据我所知,分叉一个进程会导致进程数据的完整副本,并且不同的进程在不同的地址空间中运行。
那么 Go 程序中的全局变量呢?它们与多个 goroutine 一起使用是否安全?它们是否以某种方式在系统进程之间同步?如果他们这样做了,那怎么办?我主要关心linux和freebsd的实现。
【问题讨论】:
-
还有this article。
-
@chrk,问题是:官方文档和第二篇文章都没有阐明 go runtime 如何提供共享变量的同步。官方文档指出:“一个 goroutine 有一个简单的模型:它是一个与同一地址空间中的其他 goroutine 并发执行的函数”。但是如果它们在不同的进程中,它们就不能在同一个地址空间中......
-
那么让我们再仔细阅读一遍。它指出:“它们之所以被称为 goroutines,是因为现有的术语——线程、协程、进程等等——传达了不准确的含义";所以不要假设它们是过程。就地址空间而言,它指出“Goroutines are multiplexed on multiple OS threads”。我不打算在这里提供完整的答案,但是您真正需要按顺序学习要自己找出问题的答案,是线程在 Linux 中的工作方式;然后测试:
strace,/proc/<PID>/*并在 SO 中查看一些答案以获得更高级的内容 -
Linux 中的线程也称为轻量级进程 (tldp.org/FAQ/Threads-FAQ/Types.html)。每个线程都可以在一个单独的核心上并拥有自己的堆栈,但共享生成进程的地址空间(共享内存)
标签: linux go process ipc shared-memory