我是go的初学者,我今天写了一个问题代码。本意是让资源生成和消费的时候同时打印出该资源信息。
但是该程序会导致死锁,有没有什么解决方法能保证输出信息和管道同步
```go
var mu sync.Mutex
func produce(ch chan<- int){
for i:=0;i<10;i++{
mu.Lock()
ch<-i
fmt.Println("produce:"+strconv.Itoa(i))
mu.Unlock()
}
}
func consumer(ch <- chan int){
for i:=0;i<10;i++{
mu.Lock()
v:=<-ch
fmt.Println("consumer:"+strconv.Itoa(v))
mu.Unlock()
}
}
func main(){
ch:=make(chan int,5)
go produce(ch)
go consumer(ch)
time.Sleep(10*time.Second)
}
```
个人理解,你在对通道元素的发送、接收外部封装了锁,确实保证了同一时间要么在向通道写元素,要么在从通道里面读元素,但是由于发送/接收操作都在go routine中实现,因此两种情况会出现死锁:
* 接收操作先获取到锁:此时由于通道中没有元素,接收的routine会一直阻塞,且由于锁的原因,发送routine始终无法竞争到锁,更别提向通道发送元素
* 发送routine连续5次竞争到锁或者接收routine连续5次竞争到锁的情况:由于通道容量只有5,连续接收5个或者连续发送5个元素后均无法再继续操作,此时也会阻塞
#14
更多评论
个人理解不一定正确: produce在执行第五次的时候,ch已经执行mu.Lock(),此时ch已满,通道阻塞,但是mu.Unlocl没有释放锁,所以造成了持续阻塞。
#1