关于 Goroutine 的一些使用细节

来源:互联网 发布:法国留学知乎 编辑:程序博客网 时间:2024/05/29 05:13
我一向认为一篇 blog 需要使用给出使用场景,才有借鉴意义,所以本文会先给出使用场景,然后给出解决方案。本文只是记录,并不代表本人的创新。

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

package mainimport (    "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 mainimport (    "fmt"    "sync")var waitGroup sync.WaitGroupfunc test() {    defer waitGroup.Done()    fmt.Println("test")}func main() {    waitGroup.Add(1)    go test()    fmt.Println("main")    waitGroup.Wait()}

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

package mainimport (    "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")    }}

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

原创粉丝点击