看了標題就會知道講的其實都是同樣的東西,但是以官方文黨來看的話似乎是"夠程" ( Goroutine ) 才是正確的。
那麼在 Golang 裡 如何產生一個 Goroutine 呢?
這是一個普通的函數:
func A(){
fmt.Println("A")
}
按照以前我們調用函數的方式,還是單一 Goroutine,例如這樣呼叫:
A()
如果要讓他並發(產生新的 Thread),則可以這樣寫:
go A()
很簡單吧,這樣就可以產生一個新的 Goroutine
但是你會發現,他實際上在跑的時候還是單 Goroutine 阿,例如以下代碼的輸出結果:
package main
import (
"fmt"
)
func main() {
go A()
for {
fmt.Println("B")
}
}
func A() {
for {
fmt.Println("A")
}
}
他的輸出結果是 :BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
完全不會出現 ABABAB 這種類型的交錯,這是為什麼呢?
原來在 Go 語言裡 預設只有單一 Thread 在跑,所以我們要加上這一行:runtime.GOMAXPROCS(4)
注意這個 runtime.GOMAXPROCS(4) 代表我有 4 顆物理核心,就是4核心的意思,請依需求修改你的代碼
範例:
package main
import (
"fmt"
"runtime"
)
func main() {
runtime.GOMAXPROCS(4)
go A()
for {
fmt.Println("B")
}
}
func A() {
for {
fmt.Println("A")
}
}
輸出結果:ABBAABBABBBABABABABA
可以發現這樣就是併發執行 Go 程式了 !!
再來看一下其他例子:
package main
import (
"fmt"
)
func main() {
go Hello()
}
func Hello(){
fmt.Println("Hello")
}
你會發現這個程式居然不會出出結果!! 明明看上去沒有 Bug 的說。原來,這個原因是 main() Thread 比 Hello() Thread 還要早結束!! 然而當 main() 結束了...理所當然 Hello() 也會一起結束...所以我們要把程式修改成:
package main
import (
"fmt"
)
func main() {
go Hello()
time.Sleep(time.Second * 1) // 暫停一秒鐘
}
func Hello(){
fmt.Println("Hello")
}
因為讓 main() 暫停一秒,所以 Hello() 有足夠的時間跑完,理所當然我們就可以看見他輸出:Hello
雖然是這樣講...但是請以後不要像我這樣寫,我上面只是講原理,實際上應該使用 "通道" (Channel) ,使用通道後"主"線程可以與"子"線程做溝通,詳細程式碼...請待續...( 先去吃飯了 XD
留言列表