跳到主要内容

Go 协程

提示
  1. 并发编程的基础: Go中的goroutine用于创建并发程序,允许同时运行多个进程。
  2. 创建和使用Goroutine: 通过在函数调用前加go关键字,可以将普通函数转换为goroutine,实现函数的异步执行。
  3. Goroutines的交互和优势: 多个goroutine并发运行,执行顺序随机。Goroutines提高了并发性能,适用于背景操作,通过私有通道安全通信,可分割任务以提升效率。

在 Go 中,我们使用 goroutines 来创建并发程序。并发程序能够同时运行多个进程。

假设我们有一个程序包含两个独立的函数。在普通程序中,这两个函数将同步执行。也就是说,第二个函数只有在第一个函数执行完毕后才执行。

然而,由于这两个函数是独立的,如果我们能够异步地同时执行这两个函数,将会更高效。

为此,我们使用 goroutines 来帮助我们在编程中实现并发。

创建 Goroutine

我们可以通过使用 go 关键字调用函数,将常规函数转换为 goroutine。例如,

func display() {
// 函数内部的代码
}

// 启动 goroutine
go display()

这里,display() 是一个 goroutine。

示例:Goroutine

现在让我们看一个使用 goroutine 的并发编程的实例。

package main
import (
"fmt"
"time"
)

// 创建一个函数
func display(message string) {

fmt.Println(message)
}

func main() {

// 调用 goroutine
go display("进程 1")

display("进程 2")
}

输出

进程 2

在上述示例中,我们两次调用了 display() 函数:

  • go display("进程 1") - 作为 goroutine
  • display("进程 2") - 常规函数调用

在正常执行中,程序控制权会在第一次函数调用期间转移到函数中,一旦执行完成,它就会返回到下一个语句。

在我们的示例中,下一个语句是对函数的第二次调用。所以,首先应该打印 进程 1,然后是 进程 2

然而,我们只获得了 进程 2 的输出。

这是因为我们在第一个函数调用时使用了 go,所以它被视为 goroutine。函数独立运行,并且 main() 函数现在并发运行。

因此,第二次调用立即执行,程序在完成第一个函数调用之前终止。

在使用 Goroutine 的程序中,进程的执行是并发的。

使用 Goroutine 并发运行两个函数

在并发程序中,main() 总是一个默认的 goroutine。如果 main() 没有执行,其他 goroutines 将无法执行。

因此,为了确保所有 goroutines 在 main 函数结束之前执行完毕,我们让进程睡眠,以便其他进程有机会执行。

// 程序并发运行两个 goroutines

package main
import (
"fmt"
"time"
)

// 创建一个函数
func display(message string) {

// 无限循环
for {
fmt.Println(message)

// 让进程睡眠 1 秒
time.Sleep(time.Second * 1)
}
}

func main() {

// 用 goroutine 调用函数
go display("进程 1")

display("进程 2")

}

输出

进程 3
进程 2
进程 1

在上述示例中,我们在函数定义中添加了一行。

time.Sleep(time.Second * 1)

这里,当 display("进程 2") 正在执行时,time.Sleep() 函数会使进程暂停 1 秒。在这 1 秒内,goroutine go display("进程 1") 将被执行。

这样,函数在 main() 函数停止之前并发运行。

多个 Goroutines

当多个 Goroutines 一起运行时,它们彼此并发地互相交互。goroutine 的执行顺序是随机的,所以我们可能得不到预期的输出。例如,

// 用于展示多个 goroutines 的程序

package main

import (
"fmt"
"time"
)

func display(message string) {

fmt.Println(message)

}

func main() {

// 运行两个不同的 goroutine
go display("进程 1")
go display("进程 2")
go display("进程 3")

// 使主 goroutine 休眠 1 秒
time.Sleep(time.Second * 1)
}

输出

进程 1
进程 1
.
.
进程 3
进程 2
进程 2
.
.

这里,所有的 goroutines 都并发运行,休眠时间为 1 秒。执行顺序是随机的,所以每次运行程序时,我们得到的输出都不同。

Goroutines 的好处

以下是 goroutines 的一些主要好处。

  • 通过 Goroutines,在 Go 编程中实现了并发。它帮助两个或多个独立函数一起运行。
  • Goroutines 可用于在程序中运行后台操作。
  • 它通过私有通道进行通信,所以它们之间的通信更安全。
  • 通过 goroutines,我们可以将一个任务分成不同的部分来更好地执行。