关于 Goroutine 的一些使用细节

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Koprvhdix/article/details/78476239
我一向认为一篇 blog 需要使用给出使用场景,才有借鉴意义,所以本文会先给出使用场景,然后给出解决方案。本文只是记录,并不代表本人的创新。

在使用 Go 语言的 go 关键字的时候,总是有一种错觉:goroutine 没有执行。下面给一个简单的例子:

package main

import (
    "fmt"
)

func test() {
    fmt.Println("test")
}

func main() {
    go test()
    fmt.Println("main")
}

得到的输出基本只有 main 不会有 test。然后我就错误地认为:goroutine 在没有使用 channel 的时候是不会执行的。当然稍作修改就发现自己错了,最简单的就是在最后一行加上

time.sleep(2e9)

这样一来,main 和 test 都有输出了。在当前案例可以看出 goroutine 是有执行的。那么结论应该就是:主线程在新创建的 goroutine 没有结束的时候直接结束了。那么我们应该做的是等待新创建的 goroutine 结束,或者用 channel 让主线程得到新创建的 goroutine 结束的信号再结束。

等待新创建的 goroutine 结束,要使用 sync.WaitGroup

package main

import (
    "fmt"
    "sync"
)

var waitGroup sync.WaitGroup

func test() {
    defer waitGroup.Done()
    fmt.Println("test")
}

func main() {
    waitGroup.Add(1)
    go test()
    fmt.Println("main")
    waitGroup.Wait()
}

关于 channel 的使用,教程很多,这里给一个简单的。注意要创建有缓冲 channel。对了,再记录一下 Go 语言的名言:不要用共享内存去通信,而要用通信去共享内存。

package main

import (
    "fmt"
)

var testStatus = make(chan int, 1)

func test() {
    fmt.Println("test")
    testStatus <- 0
}

func main() {
    go test()
    fmt.Println("main")
    select {
    case _ = <-testStatus:
        fmt.Println("finish")
    }
}

路漫漫其修远兮,加油!!

猜你喜欢

转载自blog.csdn.net/Koprvhdix/article/details/78476239