Goroutine和线程都属于并发执行的实体,但是有以下几点主要区别:
- 实现:Goroutine是由Go语言的运行时(runtime)管理的轻量级线程,线程是由操作系统内核调度和管理的。
- 调度:Goroutine的调度由Go语言的runtime进行,线程的调度由操作系统进行。
- 栈大小:Goroutine的栈从2KB开始并且可扩展,线程的栈大小由操作系统确定,通常为2MB。
- 创建消耗:创建Goroutine的成本较低,因为Goroutine的栈可以按需增长。而创建线程的成本较高,因为其固定的栈大小由操作系统决定。
- 数量:可创建的Goroutine数量远大于线程数量,一个程序可创建上万个Goroutine,但线程数量受操作系统限制,一般为上千个。
例如:
使用Goroutine:
func sayHello() {
for i := 0; i < 10; i++ {
fmt.Println("Hello from Goroutine!")
}
}
func main() {
go sayHello() // 创建一个Goroutine运行sayHello()函数
fmt.Println("Hello from main!")
}
使用线程:
func sayHello() {
for i := 0; i < 10; i++ {
fmt.Println("Hello from thread!")
}
}
func main() {
var wg sync.WaitGroup
wg.Add(1)
go func() {
sayHello()
wg.Done()
}()
wg.Wait()
fmt.Println("Hello from main!")
}
可以看出,Goroutine的创建和使用都更简单方便。Goroutine作为Go语言并发的基本执行实体,其效率和易用性使Go语言成为并发编程的首选语言之一。