channel死锁

package main

import (
    "fmt"
    "time"
)

//单向写通道(生产者):
func producer(send chan<- int) {
    for i := 0; i < 3; i++ {
        send <- i
        fmt.Println("生产者:", i)
    }
    //关闭单向写通道
    close(send)
}
//单向读通道(消费者):
func consumer(recv <-chan int) {
    for {
        if sum, ok := <-recv; ok {
            fmt.Println("接收者:", sum)
        } else {
            fmt.Println("接收完毕")
            break
        }
    }
}
//单向通道的使用(生产者消费者模型)
func main() {
    ch := make(chan int)
    //生产者子go程
    go producer(ch)
    time.Sleep(time.Second)
    //消费者主go程
    consumer(ch)
}

运行结果:
**接收者: 0
生产者: 0
生产者: 1
接收者: 1
接收者: 2
生产者: 2
接收完毕
Process finished with exit code 0**

1,单向写通道中假若关闭通道未写,会报死锁bug,all goroutines are asleep - deadlock!为什么呢?
因为如果不关闭写通道,等读通道读不到内容的时候主go程会一直阻塞,进程一直占用系统资源不释放,所以会发生死锁
运行结果:
**接收者: 0
生产者: 0
生产者: 1
接收者: 1
接收者: 2
goroutine 1 [chan receive]:
生产者: 2
main.consumer(0xc42006a060)
/Users/zhuyp/go/src/awesomeProject1/0825test.go:67 +0x66
main.main()
/Users/zhuyp/go/src/awesomeProject1/0825test.go:82 +0x78
Process finished with exit code 2**

2,假若把consumer(ch)也改成子go程,
func main() {
ch := make(chan int)
//生产者子go程
go producer(ch)
time.Sleep(time.Second)
//消费者子go程
go consumer(ch)
//主go程
for i:=0;i<4;i++{
fmt.Println("kkkkkkk")
}
}

运行结果:
**接收者: 0
生产者: 0
生产者: 1
接收者: 1
接收者: 2
生产者: 2
kkkkkkk
kkkkkkk
kkkkkkk
kkkkkkk
Process finished with exit code 0**
这样就不会报出死锁错,因为在子go程(consumer)中读操作阻塞,主go程会争抢资源,运行主go程,主go程运行结束,切断子go程的等待资源事件,整个进程随之结束,所以不会报错
3,如果主go程中只有读channel,只有写channel或者同时有读写channel 会发生死锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值