Channel 的死锁

Channel 的死锁

  • 1没有缓冲区的channel

代码1

func f(){
    ch := make(chan int)
    ch <- 1
    fmt.Println(<-ch)
}

代码2

func f(){
    ch := make(chan int,1)
    ch <- 1
    fmt.Println(<-ch)
}

以上代码中代码1会死锁,代码2不会死锁
因为在吗1 中的channel没有缓冲区,而代码2中的channel有缓冲区
没有缓冲区的channel只能通过goroutine去读,否则就会发生死锁

  • 2 channel 如果有缓冲区,并且不适用goroutine,则必须先写后读

如下代码会发生死锁

func f(){
    ch := make(ch int ,1)
    fmt.Println(<-ch)
    ch<-1
}
  • 3 channel 的缓冲区已满继续写入时会发生死锁
func f(){
    ch := make(chan int,1)
    ch <- 1
    ch <- 2 // 死锁,缓冲区已经满了。继续写入
    fmt.Println(<-ch)
}

由此可见channel的死锁可以确认为向缓冲区已满的channel中写入数据,或者从缓冲区为空的channel中读取数据导致。
即.如果channel没有缓冲区,则在向channel写入数据时必须有一个goroutine已经准备就绪读取数据

如果channel带有缓冲区,则必须在缓冲区未满的时候写入数据否则就会死锁

在读取缓冲区数据时必须等缓冲区有数据才可以读取。否则就会出现死锁。除非使用 goroutine

猜你喜欢

转载自www.cnblogs.com/pmsl/p/9691454.html