1. 当管道写满了,写会阻塞
2. 当缓冲区读完了,读阻塞
3. 如果管道没有使用make分配空间,管道默认是nil,从nil的管道读取数据,写入数据,都会阻塞(程序不会奔溃)
4. 从一个已经close的管道读取数据时,会返回零值(程序不会奔溃)
5. 向一个已经close的管道写数据时,会奔溃
6. 关闭一个已经close的管道,程序会奔溃
7. 关闭管道的动作,一定要写端关闭,不应该放到读端,否则会写奔溃
8. 读和写的次数,一定对等,否则,1.存在内存泄漏,2.在主go程中,程序奔溃(deadlock)
9. 判断管道是否已经关闭
v,ok:= <- intChan // ok为0 管道关闭
10. 单向通道 1. 单向写通道 chan <- int 2. 单向读通道 <- chan int
func main() {
intChan := make(chan int,5)
go a(intChan)
go b(intChan)
for true {}
}
// 写
func a(intChan chan <- int) {
for i := 0; i < 50; i++ {
intChan <- i
}
}
// 读
func b(intChan <- chan int) {
for i := range intChan {
fmt.Println(i)
}
}
11. select 当程序中有多个channel协同工作,某一刻,chan1或chan2触发了
func main() {
intChan1 := make(chan int)
intChan2 := make(chan int)
go func() {
for i := 0; i < 20; i++ {
intChan1 <- i
time.Sleep(1 * time.Second / 2)
}
}()
go func() {
for i := 0; i < 20; i++ {
intChan2 <- i
time.Sleep(1 * time.Second / 3)
}
}()
go func() {
for true {
select {
case data := <-intChan1:
fmt.Println(data, "===")
case data2 := <-intChan2:
fmt.Println(data2, "---")
default:
time.Sleep(2 * time.Second)
fmt.Println("结束中")
}
}
}()
for true {
fmt.Println("主进程执行中")
time.Sleep(5 * time.Second)
}
}
发表评论