铁人赛终於要过一半了,今天要来介绍 Go 的特色之一 -- Goroutines。
那麽话不多说,我们就进入正题吧 ─=≡Σ(((っ゚∀゚)っ
事前提要:必须先了解 thread 是什麽!
Goroutines 是由 Go runtime 管理的轻量 thread。
刚刚有提到,他能够让程序「同步」执行,但事实上 concurrency(并发)并不是真的同步,而是透过 thread 共享讯息,并且将资源分段处理不同的事情。
简单的说,就是时间管理大师的概念,在一定的时间内把所有事情给处理完成。
如果对昨天的文章还有印象就会知道 Goroutines 的起手式,就是 go
!
go f(x, y, z)
有了 go
做为起手式後,f
函式因此能跑在另一个 Goroutine 上。
咦,为什麽会说跑在「另一个」Goroutine 呢?
因为 Go 的程序里会有一个主要的 main goroutine,而这东西就是我们每次都会用到的 main
函式,每当 main
函式执行完成後,就会强制把所有的 gorountine 给关闭掉。
不太了解为什麽吗?让我们来 try try see!
package main
import (
"fmt"
)
func say(s string) {
for i := 0; i < 5; i++ {
fmt.Println(s)
}
}
func main() {
go say("world")
go say("hello")
}
这时候应该会发现毫无反应,这是因为现在这个状态总共开了 3 个 gorountine:main
、 say("world")
、 say("hello")
,每个 goroutine 会乖乖排队等待被执行,但 main
执行完後根本还没轮到剩下的两个,就强制关闭了所有的 goroutine。
要解决这个问题,就需要阻塞住 goroutine,这样原本在运作的 A goroutine 忽然闲下来了,时间管理大师就能够赶快再去 B goroutine 处理事情。
有三种方式能够处理这问题:
time.Sleep()
sync.WaitGroup
// time.Sleep()
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
fmt.Println(s)
}
}
func main() {
go say("world")
go say("hello")
time.Sleep(100 * time.Millisecond)
}
// sync.WaitGroup
package main
import (
"fmt"
"sync"
"time"
)
func say(s string, wg *sync.WaitGroup) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
wg.Done()
}
func main() {
wg := new(sync.WaitGroup)
wg.Add(2)
go say("world", wg)
go say("hello", wg)
wg.Wait()
}
至於 channel 怎麽使用,就交给明天的文章了
有任何问题欢迎与我告知 :)
本篇文章同步更新於我的部落格
目录 游戏机制介绍 制作前言 简单Particle System(粒子系统)-水柱制作 游戏机制介...
前天讲阵列的时候有写到for(i=0; i < a.length; i++) 这是还没讲到的回...
前言 我们学习了效能优化、生命周期、React状态等等,今天我们要来学习React的模组化,也就是c...
昨天跟大家介绍了网页首图的媒材,那今天针对图片展示的部分来做一个分享,整理出几个常见的网页排版,可以...
前面我们认识的都是"two stage"的方法,在整体的运行过程上没有那麽快速,所以在很多行动装置上...