go中最重要的一种通信通道就是channel
1.给一个 nil channel 发送数据,造成永远阻塞
2.从一个 nil channel 接收数据,造成永远阻塞
3.给一个已经关闭的 channel 发送数据,引起 panic
4.从一个已经关闭的 channel 接收数据,立即返回一个零值
package main
import "fmt"
// 此channel没有设置缓存,将被阻塞,所以都是执行default
func main() {
messages := make(chan string)
signals := make(chan bool)
select {
case msg := <-messages:
fmt.Println("received message", msg)
default:
fmt.Println("no message received")
}
msg := "hi"
select {
case messages <- msg:
fmt.Println("sent message", msg)
default:
fmt.Println("no message sent")
}
select {
case msg := <-messages:
fmt.Println("received message", msg)
case sig := <-signals:
fmt.Println("received signal", sig)
default:
fmt.Println("no activity")
}
}
// 输出
// no message received
// no message sent
// no activity
Closing Channels.
package main
import "fmt"
// 这个例子在执行workder的工作时使用jobs管道来监听
// 当jobs关闭了,表示worker执行完毕,开始退出goroutine
// goroutine的退出又使用done来监听
func main() {
jobs := make(chan int, 5)
done := make(chan bool)
go func() {
for {
j, more := <-jobs
if more {
fmt.Println("received job", j)
} else {
fmt.Println("received all jobs")
done <- true
return
}
}
}()
// 发送三个jobs worker执行
for j := 1; j <= 3; j++ {
jobs <- j
fmt.Println("sent job", j)
}
close(jobs)
fmt.Println("sent all jobs")
// worker被关闭
<-done
}
// 输出
// sent job 1
// received job 1
// sent job 2
// received job 2
// sent job 3
// received job 3
// sent all jobs
// received all jobs
Range over Channels.
package main
import "fmt"
// 遍历channel 有两种方法:select和range
// select 在channel输入或输出才能走case
// range可以再channel 甚至close后都能遍历值
func main() {
queue := make(chan string, 2)
queue <- "one"
queue <- "two"
close(queue)
for elem := range queue {
fmt.Println(elem)
}
}
// 输出
// one
// two
Timers
package main
import "time"
import "fmt"
// time.NewTimer 定时一次
// 说明time是阻塞输出
func main() {
// 定时2s
timer1 := time.NewTimer(time.Second * 2)
// 阻塞输出
<-timer1.C
fmt.Println("Timer 1 expired")
timer2 := time.NewTimer(time.Second)
go func() {
<-timer2.C
fmt.Println("Timer 2 expired")
}()
stop2 := timer2.Stop()
if stop2 {
fmt.Println("Timer 2 stopped")
}
}
// 输出
// Timer 1 expired
// Timer 2 stopped
Tickers
package main
import "time"
import "fmt"
// ticker 定时循环
func main() {
ticker := time.NewTicker(time.Millisecond * 500)
go func() {
for t := range ticker.C {
fmt.Println("Tick at", t)
}
}()
time.Sleep(time.Millisecond * 1600)
ticker.Stop()
fmt.Println("Ticker stopped")
}
// 输出
// Tick at 2012-09-23 11:29:56.487625 -0700 PDT
// Tick at 2012-09-23 11:29:56.988063 -0700 PDT
// Tick at 2012-09-23 11:29:57.488076 -0700 PDT
// Ticker stopped
有疑问加站长微信联系(非本文作者)