最近刚入门golang 学到了channel 自己仿照模板在main函数里写了一个单向通道的小demo 但是跑不出想要的效果 想请教各位大佬 帮我看看是哪个地方出现了问题
代码如下
```go
c := make(chan int)
go func(out chan<- int) {
fmt.Println("product func")
mutex.Lock() //加锁保证对通道的占用
for i:=0 ; i<= 5;i++{
out <- i
}
mutex.Unlock()
fmt.Println("product func end")
}(c)
go func(in <-chan int ) {
fmt.Println("consumer function")
for num := range in{
fmt.Println(num)
}
fmt.Println("consumer function end")
}(c) //把双向channel传入 单向channel作为参数的函数 中
```
运行结果啥也没有
![1.png](https://static.studygolang.com/211027/a26fa2c351397f07dc54bf39c31f424f.png)
--------------------------------分割线------------------------------------------
经过前两楼的大佬的指定 ,知道了之前的原因是main goroutine挂的太快
但是我结合3l大哥的回复想了一下,在自己的程序里 “无缓冲通道+锁” 按道理应该会造成 “写段阻塞”报错 但实际运行起来却没有问题,有老哥能帮忙分析一下是什么原因吗?
修改以后的代码
```go
c := make(chan int)
go func(out chan<- int) {
fmt.Println("product func")
defer close(c)
mutex.Lock() //加锁保证对通道的占用
for i:=0 ; i<= 5;i++{
out <- i
}
mutex.Unlock()
fmt.Println("product func end")
}(c)
go func(in <-chan int ) {
fmt.Println("consumer function")
for num := range in{
fmt.Println(num)
}
fmt.Println("consumer function end")
}(c) //把双向channel传入 单向channel作为参数的函数 中
time.Sleep(5*time.Second)
/*
主线程挂了之后,程序会直接退出,你启动的两个协程还没来得及运行,程序已经退出了。在最后面加个sleep 或者用sync.WaitGroup
*/
```
![QQ截图20211027153711.png](https://static.studygolang.com/211027/8abd6bc48c7db9a264cbea6bbd63bfb4.png)
改成这样,你才能让他阻塞,2个协程去抢同一把锁才会阻塞,你只有一个协程拿锁,不会阻塞的。
``` go
c := make(chan int)
mutex := sync.Mutex{}
go func(out chan<- int) {
fmt.Println("product func")
defer close(c)
mutex.Lock() //加锁保证对通道的占用
for i:=0 ; i<= 5;i++{
out <- i
}
mutex.Unlock()
fmt.Println("product func end")
}(c)
go func(in <-chan int ) {
mutex.Lock() //加锁保证对通道的占用
fmt.Println("consumer function")
for num := range in{
fmt.Println(num)
}
mutex.Unlock()
fmt.Println("consumer function end")
}(c) //把双向channel传入 单向channel作为参数的函数 中
time.Sleep(5*time.Second)
```
这样你程序就只会打印
```
product func
consumer function
```
然后5秒自己退出
#6
更多评论