goroutine详解

目录

一、创建 goroutine

1、启动单个协程

2、使用goroutine的问题

3、启动多个goroutine

二、使用匿名函数创建goroutine


一、创建 goroutine

        Go 程序中使用 go 关键字为一个函数创建一个 goroutine。一个函数可以被创建多个 goroutine,一个 goroutine 必定对应一个函数。

go 函数名( 参数列表 )

        使用 go 关键字创建 goroutine 时,被调用函数的返回值会被忽略。如果需要在 goroutine 中返回数据,就要使用通道(channel)特性,通过通道把数据从 goroutine 中作为返回值传出。

扫描二维码关注公众号,回复: 13922126 查看本文章

1、启动单个协程

func running() {
    fmt.Println("Hello Goroutine!")
}

func main() {
    go running() // 启动另外一个goroutine去执行hello函数
    fmt.Println("main goroutine done!")
}

        程序在启动时,运行时(runtime)会默认为 main() 函数创建一个 goroutine。在 main() 函数的 goroutine 中执行到 go running 语句时,归属于 running() 函数的 goroutine 被创建,running() 函数开始在自己的 goroutine 中执行。此时,main() 继续执行,两个 goroutine 通过 Go 程序的调度机制同时运作。

2、使用goroutine的问题

这一次的执行结果只打印了main goroutine done!,并没有打印Hello Goroutine!。为什么呢?

1)在程序启动时,Go程序就会为main()函数创建一个默认的goroutine(主协程)。

2)当main()函数返回的时候该goroutine就结束了,所有在main()函数中启动的goroutine会一同结束

所以我们要想办法让主协程等等其他协程,最简单粗暴的方式就是time.Sleep了。

func main() {
    go hello() // 启动另外一个goroutine去执行hello函数
    fmt.Println("main goroutine done!")
    
    time.Sleep(time.Second) //停顿一秒,这种方法不好,见channel阻塞/死锁详解
}

3、启动多个goroutine

var wg sync.WaitGroup

func hello(i int) {
    defer wg.Done() // goroutine结束就登记-1
    fmt.Println("Hello Goroutine!", i)
}
func main() {

    for i := 0; i < 10; i++ {
        wg.Add(1) // 启动一个goroutine就登记+1
        go hello(i)
    }
    
    wg.Wait() // 等待所有登记的goroutine都结束
}

多次执行上面的代码,会发现每次打印的数字的顺序都不一致。这是因为10个goroutine是并发执行的,而goroutine的调度是随机的。

二、使用匿名函数创建goroutine

go 关键字后也可以为匿名函数或闭包启动 goroutine。

go func( 参数列表 ){
    函数体
}( 调用参数列表 )

在 main() 函数中创建一个匿名函数并为匿名函数启动 goroutine。匿名函数没有参数。

package main
import (
    "fmt"
    "time"
)

func main() {
    go func() {
        var times int
        for {
            times++
            fmt.Println("tick", times)
            time.Sleep(time.Second)
        }
    }()
    
    var input string
    fmt.Scanln(&input)
}

总结:

1)所有 goroutine 在 main() 函数结束时会一同结束

2)goroutine 虽然类似于线程概念,但是从调度性能上没有线程细致,而细致程度取决于 Go 程序的 goroutine 调度器的实现和运行环境

猜你喜欢

转载自blog.csdn.net/demored/article/details/124116021