一. 死锁

  • 在主goroutine中向无缓存channel添加内容或在主goroutine中向channel添加内容且添加内容的个数已经大于channel缓存个数就会产生死锁

    1. fatal error : all goroutines are asleep -deadlock!
  • 死锁:在程序中多个进程(Golang中goroutine)由于相互竞争资源而产生的阻塞(等待)状态,而这种状态一直保持下去,此时称这个线程是死锁状态

  • 在Golang中使用无缓存channel时一定要注意.以下是一个最简单的死锁程序

    • 主协程中有ch<-1,无缓存channel无论添加还是取出数据都会阻塞goroutine,当前程序无其他代码,主goroutine会一直被阻塞下去,此时主goroutine就是死锁状态
      1. func main() {
      2. ch := make(chan int)
      3. ch <- 1
      4. }
  • 而下面代码就不会产生死锁

    • 通过代码示例可以看出,在使用无缓存channel时,特别要注意的是在主协程中有操作channel代码 ```go package main

import ( “time” “fmt” )

func main() { ch := make(chan int) go func() { ch <- 1 fmt.Println(“执行goroutine”) }() time.Sleep(5e9) fmt.Println(“程序执行结束”) }

  1. <a name="ad2c23f7"></a>
  2. # 二. 有缓存通道
  3. - 创建一个有缓存通道
  4. ```go
  5. func main() {
  6. ch := make(chan int, 3) //缓存大小3,里面消息个数小于等于3时都不会阻塞goroutine
  7. ch <- 1
  8. ch <- 2
  9. ch <- 3
  10. ch <- 4 //此行出现死锁,超过缓存大小数量
  11. }
  • 在Golang中有缓存channel的缓存大小是不能改变的,但是只要不超过缓存数量大小,都不会出现阻塞状态 ```go package main

import “fmt”

func main() { ch := make(chan int, 3) //缓存大小3,里面消息个数小于等于3时都不会阻塞goroutine ch <- 1 fmt.Println(<-ch) ch <- 2 fmt.Println(<-ch) ch <- 3 ch <- 4 fmt.Println(len(ch))//输出2,表示channel中有两个消息 fmt.Println(cap(ch))//输出3,表示缓存大小总量为3 } ```