之前簡單介紹了golang在網路與資料庫的應用,
現在回到concurrent.Golang是使用goroutine透過channel來傳遞
message.之前的範例,看似很簡單,實際上channel是會block的.
今天來看看這方面的例子.
// hello65
// channel_block
package main
import (
"fmt"
)
func 發送(ch chan int) {
for i := 0; ; i++ {
ch <- i
}
}
func main() {
ch1 := make(chan int)
go 發送(ch1)
fmt.Println(<-ch1)
}
執行結果:
./hello65
只傳送了第一個,就是0.
因為main()只有向channel拉了一次,發送()裡面雖然是無窮迴圈,
但是都卡住了,也就是block住了.
接著看一個傳送,一個接收,兩個goroutine,main()會等待一秒後結束整個程式.
// hell066
// channel_block2
package main
import (
"fmt"
"time"
)
func pump(ch chan int) {
for i := 0; ; i++ {
ch <- i
}
}
func suck(ch chan int) {
for {
fmt.Println(<-ch)
}
}
func main() {
ch1 := make(chan int)
go pump(ch1)
go suck(ch1)
time.Sleep(time.Second)
}
執行結果如下圖:
在一秒內,傳到了 82010.
接著看以下的例子:
// hello67
// channel_block3
package main
import (
"fmt"
"time"
)
func 接收者(ch chan string) {
// 先睡個20秒吧
time.Sleep(time.Second * 20)
// 接收
x := <-ch
fmt.Printf("接收者:在 %v 收到 :%s\n", time.Now(), x)
}
func main() {
mainch := make(chan string)
go 接收者(mainch)
fmt.Printf("Main():在 %v 開始傳送\n", time.Now())
mainch <- "蠻可愛的Golang!"
fmt.Printf("Main():在 %v 完成傳送\n", time.Now())
}
執行結果:
./hello67
Main():在 2014-10-15 22:38:49.190810796 +0800 CST 開始傳送
接收者:在 2014-10-15 22:39:09.191128211 +0800 CST 收到 :蠻可愛的Golang!
Main():在 2014-10-15 22:39:09.19117098 +0800 CST 完成傳送
可以看到兩者之間的互動,等待了20秒,在接收之前,整個是block住的.