Go教程第十八篇: Goroutine

2020-05-06  本文已影响0人  大风过岗

Go教程第十八篇: Goroutine

本文是《Go系列教程》的第十八篇文章。在上一节中,我们讨论了并发的概念以及并发和并行的区别。在本文中,我们将讨论一下在Go中如何使用Goroutine实现并发。

什么是Goroutine ?

Goroutine是可以和其他函数并发的运行的函数。你可以把Goroutine想象成轻量级的线程。相比于线程,创建Goroutine的开销要小得多。因此,通常一个Go应用程序都有成千个
Goroutine并发运行。

相比较于线程,Goroutine的优势

如何启动一个Goroutine ?

在调用函数或方法的时候,加上前缀关键字go,这时,你的方法调用就变成了一个可以并发执行的Goroutine了。我们来创建一个Goroutine:

package main

import (  
    "fmt"
)

func hello() {  
    fmt.Println("Hello world goroutine")
}
func main() {  
    go hello()
    fmt.Println("main function")
}

go hello() 这行代码会启动一个新的Goroutine。此时hello()函数就会和main函数一起并发运行。main函数会在它自己的Goroutine中运行,我们称之为:main Goroutine。
运行上面的程序,输出结果只有:main function。并没有输出我们的hello函数中的内容啊,这中间到底发生了什么呢?这时,我们就需要理解一下Goroutine的俩个特性,以及为什么
会发生这种情况:

我想,现在你已经理解了为什么我们的Goroutine没有运行。在调用完go hello()之后,会立即返回,不会等待hello Goroutine执行完成,而会直接打印main function。之后,main Goroutine的优势会结束运行,因为在这行代码之后,已经没有其他需要执行的代码了,因此hello Goroutine就没有得到运行的机会。

我们来修改一下:

package main

import (  
    "fmt"
    "time"
)

func hello() {  
    fmt.Println("Hello world goroutine")
}
func main() {  
    go hello()
    time.Sleep(1 * time.Second)
    fmt.Println("main function")
}

time.Sleep(1 * time.Second)在这行代码中,我们调用了Sleep方法,sleep方法会让当前的goroutine睡眠指定的时间。在本例中,main Goroutine就会睡眠一秒。这样,在main Goroutine结束运行之前,我们的go hello(),就有足够的时间运行。程序的输出结果为:Hello world goroutine,1秒钟之后,又会输出:main function。

我们在main Goroutine中使用sleep方法,让main Goroutine等待其他Goroutine执行完成。这种方式只是为了让我们理解Goroutine的工作原理。在正式的编程中,我们可以使用channel阻塞住main Goroutine直到其他所有的Goroutine执行完成。我们将在下节中讨论channel。

启动多个Goroutine

我们再写一个程序,在这个程序中,我们会启动多个Goroutine。

package main

import (  
    "fmt"
    "time"
)

func numbers() {  
    for i := 1; i <= 5; i++ {
        time.Sleep(250 * time.Millisecond)
        fmt.Printf("%d ", i)
    }
}
func alphabets() {  
    for i := 'a'; i <= 'e'; i++ {
        time.Sleep(400 * time.Millisecond)
        fmt.Printf("%c ", i)
    }
}
func main() {  
    go numbers()
    go alphabets()
    time.Sleep(3000 * time.Millisecond)
    fmt.Println("main terminated")
}

在上面的程序中,我们启动了俩个Goroutine。这俩个Goroutine就可以并发运行了。numbers这个Goroutine初始睡眠250毫秒,之后会打印1。之后再次睡眠,打印2,一直循环直到打印出5。相似地,alphabets的Goroutines页号打印a到e,睡眠400毫秒。main Goroutine会初始化numbers和alphabets的Goroutine,同时睡眠3000毫秒,之后结束。
程序的输出如下:

1 a 2 3 b 4 c 5 d e main terminated  

下面的图就描绘了程序的工作机制:

程序是如何执行的

感谢您的阅读,请留下您珍贵的反馈和评论。Have a good Day!

备注
本文系翻译之作原文博客地址

上一篇下一篇

猜你喜欢

热点阅读