1. 程式人生 > >周威學Go從入門到放棄第十篇(多執行緒)

周威學Go從入門到放棄第十篇(多執行緒)

go語言多執行緒開發特別容易入門,通過go關鍵字實現,程式碼如下:

package main

import (
	"fmt"
	"runtime"
)

func say(s string) {
	for i := 0; i < 5; i++ {
		runtime.Gosched()
		fmt.Println(s)
	}
}

func main() {
	go say("world") //開一個新的Goroutines執行
	say("hello")    //當前Goroutines執行
}




/usr/local/go/bin/go build [/Users/zhouwei/go]
成功: 程序退出程式碼 0.
/Users/zhouwei/go/go  [/Users/zhouwei/go]
hello
hello
hello
hello
hello
成功: 程序退出程式碼 0.

 從執行結果看,好像並沒有執行      go say("world") 的內容,也沒有報錯,原因是什麼?

估計是因為main主程速度太快,來不及執行就已經結束了,嘗試一下
 

package main

import (
	"fmt"
	"runtime"
	"time"
)

func say(s string) {
	for i := 0; i < 5; i++ {
		runtime.Gosched()
		fmt.Println(s)
	}
}

func main() {
	go say("world") //開一個新的Goroutines執行
	say("hello")    //當前Goroutines執行
	time.Sleep(time.Second)
}


/usr/local/go/bin/go build [/Users/zhouwei/go]
成功: 程序退出程式碼 0.
/Users/zhouwei/go/go  [/Users/zhouwei/go]
hello
hello
hello
hello
world
hello
world
world
world
world
成功: 程序退出程式碼 0.

從列印結果看,果然加了一個休眠一秒,有結果了。具體是不是因為這個原因.

  • 當建立一個Go協程時,建立這個Go協程的語句立即返回。與函式不同,程式流程不會等待Go協程結束再繼續執行。程式流程在開啟Go協程後立即返回並開始執行下一行程式碼,忽略Go協程的任何返回值。
  • 在主協程存在時才能執行其他協程,主協程終止則程式終止,其他協程也將終止。

 執行緒通訊

go執行緒之間的通訊通過channel(看起來內部實現是個佇列)來實現的,看示例:

package main

import (
	. "fmt"
)
//從列印結果看,猜測實現是一個佇列,先入先出
var ch chan int = make(chan int)

func main() {

	go add(1, 2)
	Println(<-ch) //列印channel中的內容
	Println(<-ch) //列印channel中的內容

}

func add(a int, b int) int {
	ch <- a + b //把計算的結果存到channel中
	ch <- 1     //把計算的結果存到channel中
	return a + b
}


/usr/local/go/bin/go build [/Users/zhouwei/go]
成功: 程序退出程式碼 0.
/Users/zhouwei/go/go  [/Users/zhouwei/go]
3
1
成功: 程序退出程式碼 0.

結合示例1,2程式碼來看,channel是阻塞佇列機制,出channel中取資料,存資料都會阻塞,這也是為什麼能正常跑下去的原因(沒有因為1中所說太快直接不執行了)