一 代码
package main
import (
"fmt"
"time"
)
// write Data
func writeData(intChan chan int) {
for i := 1; i <= 50; i++ {
// 放入数据
intChan <- i
fmt.Println("writeData ", i)
// time.Sleep(time.Second)
}
close(intChan) // 关闭
}
// read data
func readData(intChan chan int, exitChan chan bool) {
for {
v, ok := <-intChan
if !ok {
break
}
time.Sleep(time.Second)
fmt.Printf("readData 读到数据=%v\n", v)
}
// readData 读取完数据后,即任务完成
exitChan <- true
close(exitChan)
}
func main() {
// 创建两个管道
intChan := make(chan int, 10)
exitChan := make(chan bool, 1)
go writeData(intChan)
// go readData(intChan, exitChan)
// time.Sleep(time.Second * 10)
for {
_, ok := <-exitChan
if !ok {
break
}
}
}
二 测试
writeData 1
writeData 2
writeData 3
writeData 4
writeData 5
writeData 6
writeData 7
writeData 8
writeData 9
writeData 10
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
E:/gocode/src/chapter16/channelapply/main.go:42 +0xa8
goroutine 18 [chan send]:
main.writeData(0xc042086000)
E:/gocode/src/chapter16/channelapply/main.go:12 +0x54
created by main.main
E:/gocode/src/chapter16/channelapply/main.go:38 +0x90
三 说明
1 如果注释掉 go readData(intChan, exitChan) 后,程序会报 deadlock 错误。
2 如果只是向管道写入数据,而没有读取,就会出现阻塞而 deadlock,原因是 intChan 容量是10,而代码 writeData会写入50个数据,因此会阻塞在 intChan <- i。
3 运行时,当发现一个管道只有写,而没有读,则该管道就会阻塞。
4 写管道的协程和读管道的协程如果频率不一致,没关系,就算写的比读的快也不会出现错误,底层编译系统会检测到并让程序正常运行。