到目前为止,对并发的本机支持是Go最受欢迎的功能之一,它使开发人员可以轻松地创建并发应用程序。 为了利用本机并发,需要使用goroutines。
Goroutines可被视为Go的主干,并且在设计固有的并发应用程序中很重要。
因此,让我们了解什么是goroutines。
可以将Goroutine与轻量级线程进行比较。 它们只是与其他功能或方法同时运行的功能或方法。
它们使我们能够在同一地址空间中同时创建和运行多个功能,并且安装成本不高。
Go使用goroutine,而其他语言(例如Java)则使用线程。 Goroutine很便宜(大约2 Kb),因为线程需要更多的堆栈空间,因此它们通常占用大量内存(从1 Mb开始)。 这使开发人员可以创建线程无法实现的大量goroutine。
所以您可能会问,为什么goroutines如此轻巧?
好吧,goroutines如此轻便的原因是因为Go不使用传统的本机线程,而是使用了绿色线程。 本机线程或OS线程具有单独的函数调用堆栈,因此它们的设置和拆卸成本非常可观。
让我们看看Go是如何做到的。
因此,在运行时,调度程序将goroutine映射到线程上,但是与Java线程中的1:1映射不同,一堆goroutine被映射到单个或一组线程上。 此外,goroutine具有灵活的堆栈大小,可根据需要扩展和缩小。 这显着减少了内存占用,并改善了goroutine的内存重新分配时间。
但是您完全不必担心所有这些漂亮的细节。
Go在运行时会处理所有这些任务,并从用户中抽象出来。
因此,用户可以做自己最擅长的事情,编写简洁高效的代码,而不必担心堆栈分段和内存重新分配。
地鼠书类似罗伯·派克(Rob Pike)的演讲goroutine的启动非常简单,只需使用关键字go即可完成 在函数或方法的前面,您就可以准备同时运行goroutine了。
package main
import (
"fmt"
)
func hello() {
fmt.Println("Hi, I'm a goroutine!")
}
func main() {
go hello()
fmt.Println("Inside main function")
}
上面的代码将创建一个goroutine与func main()
并发运行, func main()
执行它自己的goroutine,称为main goroutine。
goroutine的创建非常简单,您不必担心后台的细节,因为它们都是在Go运行时处理的。
执行代码后,您会收到一些惊喜!
Inside main function
该代码仅打印来自func main()
的消息,而不打印来自func hello()
的消息。 可以解释如下:
这就是上面我们的代码所发生的。 在呼叫go hello
,控件将消息打印在主函数中,然后程序终止。 func hello()
没有机会执行,因为主goroutine已终止并且程序结束了。
确切地说,这更多的是破解而不是修复,因为我们将程序的执行限制在现实世界的时间范围内,但这对于本示例来说就足够了。 请注意,这是一种不好的做法,应避免使用,因为实际上我们总是将通道用于任何此类同步。
package main
import (
"fmt"
"time"
)
func hello() {
fmt.Println("Hi, I'm a goroutine!")
}
func main() {
go hello()
time.Sleep(1 * time.Second)
fmt.Println("Inside main function")
}
time.sleep(1 * time.Second)
当前goroutine进入睡眠状态,并为hello goroutine提供足够的时间来完成操作。
现在,当我们运行程序时,我们得到的两条消息的间隔均为1秒。
Hi, I'm a goroutine!
Inside main function
默认情况下,Go使用的CPU线程数等于存在的CPU内核数。 您可以通过以下语句runtime.GOMAXPROCS(-1)
获得线程数runtime.GOMAXPROCS(-1)
可以通过将值从1更改为任意数字来更改线程数,但是在选择它们时必须小心。 尽管更多的线程可以提高性能,但是太多的线程可以降低进程速度,因此,理想的数量只能在运行性能扫描后确定。
Go的本机并发模型使它在创建真正的并发系统方面越来越受欢迎,而goroutines是其功能的重要组成部分。 它们可以被视为语言的心脏和灵魂,如果使用得当,它们可以大大提高性能。
我在帖子中已经多次使用并发性,但是如果您仍然想将“并发性”和“并行性”一词互换使用,那么您应该看一下Rob Pike对该主题的看法了 。
From: https://hackernoon.com/goroutines-a-general-introduction-49bed9812c94