Golang 学习 - 死锁

  • 单 go 程自己死锁

    func main()  {
    	ch := make(chan int)
    	// 向 channel 中写数据,写完后就会阻塞,等待读数据	
    	ch <- 123
    	// 由于上边已经阻塞,所以下边代码没来得及执行,造成死锁
    	num := <-ch
    	fmt.Println("num = ", num)
    }
    

    结论:channel 应该在至少 2 个以上的 go 程中进行通信。否则死锁!!!

  • go 程间 channel 访问顺序导致死锁

    func main()  {
    	ch := make(chan int)
    	// 从 channel 中读数据
    	// 因 ch 中还没有写数据,所以这里会阻塞,等待写数据
    	num := <-ch
    	// 由于上边已经阻塞,所以下边代码没来得及执行,造成死锁
    	fmt.Println("num = ", num)
    	// 虽然有两个 go 程,但是没来得及执行
    	go func() {
    		ch <- 123
    	}()
    }
    

    结论:使用 channel 一端读(写)操作,要保证另一端写(读)操作同时有机会执行。否则死锁!!!

  • 多 go 程,多 channel 交叉死锁

    func main()  {
    	ch1 := make(chan int)
    	ch2 := make(chan int)
    
    	go func() { // 子 go 程
    		for {
    			select {
    			case num := <-ch1: // 监听读取 ch1 的数据
    				// 把读取到的 ch1 的数据,给 ch2 写数据
    				ch2 <- num
    			}
    		}
    	}()
    	
    	// 主 go 程
    	for {
    		select {
    		case num := <-ch2: // 监听读取 ch2 的数据
    			// 把读取到的 ch2 的数据,给 ch1 写数据
    			ch1 <- num
    		}
    	}
    }
    

    结论:A go 程掌握 M 的同时,尝试拿 N ;B go 程掌握 N 的同时,尝试拿 M;易造成交叉死锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值