以下代码:
func main() {
goRtns := runtime.NumGoroutine()
fmt.Println("goroutines:", goRtns)
}
输出为1
。但这是在一个"过程中,"没有明确调用goroutines:
"在计算中,进程是正在执行的计算机程序的实例。它包含程序代码及其当前活动。根据操作系统(OS),进程可以由多个执行线程组成,这些执行线程同时执行指令。"
同样来自优秀的" goroutines如何运作" Krishna Sundarram的博客文章:http://blog.nindalf.com/how-goroutines-work/
"创建goroutine不需要太多内存 - 只有2kB的堆栈空间。它们通过根据需要分配和释放堆存储来增长。"
我的问题是,然后:正在运行的代码实例(我的简单main.go函数)被运行时库计为goroutine。我是否假设父进程被视为go例程,具有相同的内存分配,垃圾收集等规则?假设阅读一个关于goroutine执行的事实类似于运行它的总体进程是否明智?关于上面关于goroutines的第二个引用,这听起来像一个程序在程序执行时增加/缩小其堆栈空间的过程,这是编程中的标准范例。
流程和例程是否共享相同的规则?或者我只是遗漏了报道的goroutines数量。
答案 0 :(得分:4)
Golang中的过程是否与Goroutine相同?
您在这里使用了错误的术语process
。在GO中,一切都是goroutine。正如Volker所说。你可以从here看到gouroutine的定义:
goroutine是由Go运行时管理的轻量级线程。
例如在您的代码中
func main() {
goRtns := runtime.NumGoroutine()
fmt.Println("goroutines:", goRtns)
}
这只有一个goroutine,因为它只有main
函数,里面没有go
调用。它只是打印给定变量的东西。
另一个示例,如果您在函数go
中调用main
:
func main() {
result := sq(sq(sq(gen(1, 2, 3, 4))))
numGoroutines := runtime.NumGoroutine()
fmt.Println("number goroutine = ", numGoroutines)
fmt.Println(<-result)
fmt.Println(<-result)
fmt.Println(<-result)
fmt.Println(<-result)
}
你可以找到sq和gen函数here。现在runtime.NumGoroutine()
将有5个gorutine。由于内部函数gen
和sq
我们调用了go
,我们在这里结合主题,总数将是4 + main
,最终结果为5.
答案 1 :(得分:2)
您必须小心Go中的术语进程。您引用了一个名为 processes 的操作系统实体的定义,这些实体将被广泛认可。很多人都会明白这种用法。
但这个词过载了。 C.A.R.的工作Hoare对我们也很重要:在他的 Communicating Sequential Processes (CSP)代数中,术语进程指的是一些小东西 - 更像是一个超轻量级的线程。他的代数属于一类称为过程代数的数学。
因此,假设 goroutine 是Go的CSP 进程的实现是公平的。
在这方面,Go就像一个更老的语言,Occam。在Occam中,流程意味着CSP流程。 Occam被广泛用于裸机(即无操作系统)嵌入式编程,因此对进程一词没有任何含糊之处。