Day17-Goroutine

前言

goroutine 是 Go 语言实现并发的一种方式,在执行的过程需要少量的记忆体用量(4k~5k),以暂存自己的上下文,可在不同的时间点来分段执行程序。而 Go 语言也实作了 goroutine 之间的记忆体共用机制,并且设计了 channel 让 goroutine 之间可以进行资料沟通。

goroutine使用

Go 语言在使用 goroutine 上非常简单,只要函式前加个 go 即可。我们用 Go Tutorial 上的例子,然後先改编一下,试试看不要加 time.Sleep 看看(程序码执行到 time.Sleep 时,会停顿指定的时间)。

package main
 
import (
   "fmt"
)
 
func say(s string) {
   for i := 0; i < 5; i++ {
       fmt.Println(s)
   }
}
 
func main() {
   go say("world")
   say("hello")
}

在执行程序码後,会发现 goroutine 後的程序码并没有执行,这是因为你的主程序并没有等你的 goroutine 执行,就结束掉了,所以我们必须要让程序停顿一下,让他可以执行 goroutine :

package main
 
import (
   "fmt"
   "time"
)
 
func say(s string) {
   for i := 0; i < 5; i++ {
       time.Sleep(100 * time.Millisecond)
       fmt.Println(s)
   }
}
 
func main() {
   go say("world")
   say("hello")
}

goroutine 搭配 sync.WaitGroup

在上一个例子,我们用让程序码睡一下的方法,使得并发得以实现,但在实务上,比较少直接使用这个方法,这里要介绍另外一个方法,是使用 sync 套件里的方法 WaitGroup,来实现并发:

package main
 
import (
   "fmt"
   "sync"
)
 
var wg sync.WaitGroup
 
func count(s string) {
   fmt.Println(s)
   wg.Done()
}
 
func main() {
   wg.Add(5)
   go count("1")
   go count("2")
   go count("3")
   go count("4")
   go count("5")
   wg.Wait()
}

我们来解以上的程序码,在程序码尾端加上wg.Wait(),让他达成一些条件,才可以往後执行,而这个条件,就是收到wg.Done()的呼叫次数,而这个次数,即是wg.Add(5)里的数字5,取决於你要执行几个 goroutine,请确保这个数字要正确。

goroutine 搭配 channel

这里要介绍 goroutine 与 channel 的搭配,channel 实现了 goroutine 之间进行资料沟通,而因为也有阻塞的特性,使其可以当作等待 goroutine 的方法,这也算是最平凡的用法之一,goroutine 与 channel 真的是 Go 语言妙的设计之一。

package main
 
import (
   "fmt"
   "time"
)
 
func say(s string, c chan string) {
   for i := 0; i < 5; i++ {
       time.Sleep(time.Second)
       fmt.Println(s)
   }
   c <- "FINISH"
}
 
func main() {
   ch := make(chan string)
 
   go say("world", ch)
   go say("hello", ch)
 
   <-ch
   <-ch
}

这里起了两个 goroutine,因此需要等待两个 FINISH 推入 channel 中才能结束主程序的 goroutine。

结语

今天介绍了基本 goroutine 的使用方法,读者们可以试着执行或是改编看看。而 goroutine 及 channel 简单而强大的语法,使工程师便於开发又易於维护,是 Go 语言的优势之一。感谢您今天的阅读,希望有帮助到您!


<<:  Day10 用python写UI-聊聊文字方块Entry

>>:  [Day 11] Reactive Programming - Reactor(Scheduler)

<Day29> 实战!!投资小白的出击!!!!

时间过好快,不知不觉的已经要迈入铁人赛的最後一天了 回顾开赛到现在,除了学习Shioaji API的...

Day10 Collectionview小实作4

紧接着昨天~ 我们写了一个func 并且利用结构加入阵列的方式写入每个变数的字串以及图片。 而後在生...

Day 30 - 从写对到写好

前言 第一次参加铁人赛,完赛的这一天,简直像是学测考完走出教室的感觉!充满兴奋与骄傲! 一方面是成功...

DAY12:玉山人工智慧挑战赛-中文手写字辨识(前言)

参赛契机 之前参加资策会,结训时都会做个专题啦,但因为我自己对我们组的专题挺不满意,而且对於深度学习...

第二十七天:脱壳又称脱衣服?!

大家好我是Andy,今天来到了第二十七天,昨天讲述了加壳的技巧以及种种的工具,今天我们就来讲一下脱壳...