Golang教程

Goroutine 的概念和使用

Preview
  • Goroutine 的概念和使用
  • 什么是 Goroutine
  • Goroutine 的使用
  • Goroutine 的通信
  • Goroutine 的退出
  • 总结

Goroutine 的概念和使用

什么是 Goroutine

Goroutine 是一种轻量级线程,是 Go 语言的重要特性之一。与传统线程不同的是,Goroutine 是由 Go 语言运行时(runtime)自动管理的,而不是由操作系统管理。在实现上,Goroutine 是由 Go 语言运行时在一个普通的系统线程中执行的,可以同时存在很多个 Goroutine 并发执行。

Goroutine 的特点有:

  1. 轻量级:Goroutine 的创建和销毁开销非常小,可以轻松创建成千上万个 Goroutine。
  2. 并发性:多个 Goroutine 可以同时执行,提高了程序的并发能力。
  3. 高效性:Goroutine 的切换和调度开销非常小,可以快速切换执行不同的 Goroutine。
  4. 通信机制:Goroutine 之间可以通过 Channel 进行通信,方便实现并发协作。

Goroutine 的使用

Goroutine 的使用非常简单,只需要在函数或方法调用前加上 go 关键字即可创建一个 Goroutine。

func main() {
    go hello()
    fmt.Println("main routine")
}

func hello() {
    fmt.Println("hello goroutine")
}

上面的代码中,hello() 函数被加上了 go 关键字,表示创建了一个 Goroutine 并调用了 hello() 函数。在 main() 函数中,打印了一句话作为主程序的输出。由于 hello() 函数是在一个 Goroutine 中执行的,因此会异步执行,不会阻塞主程序的执行。

在 Goroutine 中还可以使用匿名函数的方式创建 Goroutine:

func main() {
    go func() {
        fmt.Println("hello goroutine")
    }()
    fmt.Println("main routine")
}

上面的代码中,使用了一个匿名函数创建了一个 Goroutine,并在其中打印了一句话。同样的,由于匿名函数是在一个 Goroutine 中执行的,因此会异步执行,不会阻塞主程序的执行。

Goroutine 的通信

Goroutine 之间可以通过 Channel 进行通信,Channel 是 Go 语言中用于在 Goroutine 之间进行通信的一种机制。一个 Channel 可以同时有多个 Goroutine 读取和写入数据,可以实现并发协作。

创建一个 Channel 可以使用 make 函数:

ch := make(chan int)

上面的代码中,创建了一个可以传输 int 值的 Channel。

在 Goroutine 中发送数据可以使用 ch <- 语法,接收数据可以使用 <- ch 语法:

func main() {
    ch := make(chan int)
    go func() {
        ch <- 42   // 发送数据
    }()
    x := <-ch      // 接收数据
    fmt.Println(x)
}

上面的代码中,创建了一个可以传输 int 值的 Channel,然后在一个匿名函数中向 Channel 中发送了一个值为 42 的数据。在 main() 函数中,使用 <- ch 语法从 Channel 中接收数据,并将其赋值给 x 变量,然后将 x 打印出来。

Goroutine 的退出

Goroutine 执行完成后会自动退出,不需要任何操作。但是,在某些情况下,我们需要主动关闭一个 Goroutine。例如,当我们使用 Channel 进行通信时,必须保证所有的 Goroutine 都能正常退出,否则会导致程序一直阻塞。

通过 close 函数可以关闭一个 Channel,当一个 Channel 被关闭后,所有的 Goroutine 都能够正常退出:

func main() {
    ch := make(chan int)
    go func() {
        for {
            x, ok := <-ch
            if !ok {
                break
            }
            fmt.Println(x)
        }
    }()
    ch <- 1
    ch <- 2
    close(ch)     // 关闭 Channel
}

上面的代码中,创建了一个可以传输 int 值的 Channel,然后在一个匿名函数中使用无限循环从 Channel 中接收数据,并将其打印出来。在 main() 函数中,向 Channel 中发送了两个数据,并在最后通过 close 函数关闭了 Channel。

总结

Goroutine 是 Go 语言中轻量级的并发机制,可以非常方便地实现并发程序。通过 Channel,可以实现 Goroutine 之间的通信,实现并发协作。在使用 Goroutine 和 Channel 时,需要注意一些细节,例如确保所有的 Goroutine 都能正常退出,避免死锁等问题。