golang-channel造成死锁案例

 1. 案例1,无缓冲信道导致死锁, -> 运行死锁
  // 不设定容量创建的是无缓冲信道,在接收者未准备好之前信道处于阻塞状态,

package main

func main(){

    // 例如本案例:fatal error: all goroutines are asleep - deadlock!
	// sch := make(chan string)
	// sch <- "string"
	// fmt.Println(<-sch)

	// 处理方法,使用双协程,并且接收者在发送者就绪之前,-> 运行正常
	// sch := make(chan string)
	//
	// go func() {
	// 	fmt.Println(<-sch) // 接收者就绪
	// }()
	//
    // time.Sleep(time.Second)
	// sch <- "string"
}
2.案例2,改用有缓冲的信道, -> 运行正常
package main

func main() {

	// 案例2,改用有缓冲的信道, -> 运行正常
	// sch := make(chan string, 1)
	// sch <- "hello"
	// fmt.Println(<-sch)

	// 有缓冲信道导致的死锁,因信道容量满了,再向信道添加数据会产生阻塞,后续无法消费,从而导致死锁  - >运行死锁
	// sch := make(chan string, 1)
	// sch <- "hello"
	// sch <- "world" // 因信道满了,无法接收数据从而产生阻塞
	// fmt.Println(<-sch)

	// 解决方法,生产者跟消费者区分开来,使用不同的协程
	sch := make(chan int, 1)
	go func() {
		count := 0
		for {
			sch <- count
			count++
		}
		close(sch) // 生产者不再生产消息,关闭掉通道即可
	}()
	go func() {
		for {
			fmt.Println(<-sch)
		}
	}()
	select {}

}

3. 案例3,消费者一直空等待,并无生产者再生产消息,导致程序阻塞产生死锁 -> 运行死锁

package main

func main() {

	// 案例3,消费者一直空等待,并无生产者再生产消息,导致程序阻塞产生死锁  -> 运行死锁
	// pipLine := make(chan string)
	// go func() {
	// 	pipLine <- "hello world"
	// 	pipLine <- "hello China"
	// }()
	
	// // 再无消息消费,造成另一方无穷等待,造成死锁
	// // fatal error: all goroutines are asleep - deadlock!
	// for data := range pipLine {
	// 	fmt.Println(data)
	// }

	// 解决方法
	// 生产者不再生产消息时,关掉该信道,从而避免消费者傻等待造成死锁
	go func() {
		pipLine <- "hello world"
		pipLine <- "hello China"
		close(pipline)
	}()

	select {}

}

 4.案例4,无缓冲通道,当消费者结束,生产者也应该有检测机制,发现消费者没了,应该停止生产,并关闭掉通道,否则会造成死锁,如下代码:

package main

import (
	"fmt"
)

var index uint64 = 0

func main() {

	// 案例4,无缓冲通道,当消费者结束,生产者也应该有检测机制,发现消费者没了,应该停止生产,并关闭掉通道,否则会造成死锁,如下代码:
	// fatal error: all goroutines are asleep - deadlock!
	sch := make(chan uint64)
	go func() {
		count := 0
		for {
			if count == 10 {
				// break // 消费者推出,会造成死锁
			}
			fmt.Println("read = ", <-sch)
			count++
			// time.Sleep(time.Second)
		}
	}()

	go func() {
		for {
			index++
			if index == 10 {
				index = 0
			}
			sch <- index
			// time.Sleep(time.Second)
		}
	}()

	// 处理方法,生产消费必须同时存在,或者消费者推出,生产者能感知,并且主动关闭掉通道
	// 主程
	select {}
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值