Golang中的协程和线程有何区别?

Goroutine和线程都属于并发执行的实体,但是有以下几点主要区别:

  1. 实现:Goroutine是由Go语言的运行时(runtime)管理的轻量级线程,线程是由操作系统内核调度和管理的。
  2. 调度:Goroutine的调度由Go语言的runtime进行,线程的调度由操作系统进行。
  3. 栈大小:Goroutine的栈从2KB开始并且可扩展,线程的栈大小由操作系统确定,通常为2MB。
  4. 创建消耗:创建Goroutine的成本较低,因为Goroutine的栈可以按需增长。而创建线程的成本较高,因为其固定的栈大小由操作系统决定。
  5. 数量:可创建的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语言成为并发编程的首选语言之一。