看了標題就會知道講的其實都是同樣的東西,但是以官方文黨來看的話似乎是"夠程" ( 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 

 

 

 

 

 

 

arrow
arrow
    全站熱搜

    黃彥霖 發表在 痞客邦 留言(0) 人氣()