如何解决两个goroutine同时对一个channel进行读写的问题?
请完成goroutine和channel协同工作的案例,具体要求:
1)开启一个writeData协程,向管道intChan中写入50个整数.
2)开启一个readData协程,从管道intChan中读取writeData写入的数据。
3)注意:writeData和readDate操作的是同一个管道
4)主线程需要等待writeData和readDate协程都完成工作才能退出【管道】
package main
import (
"fmt"
"time"
)
// write Data
func writeData(intChan chan int) {
for i := 1; i <= 20; i++ {
//放入数据
intChan <- i //
fmt.Println("writeData ", i)
//time.Sleep(time.Second)
}
close(intChan) //关闭
}
// read data
func readData(intChan chan int, exitChan chan bool) {
for {
v, ok := <-intChan
if !ok {
break
}
time.Sleep(time.Second)
fmt.Printf("readData 读到数据=%v\n", v)
}
//readData 读取完数据后,即任务完成
exitChan <- true
close(exitChan)
}
func main() {
//创建两个管道
intChan := make(chan int, 10)
exitChan := make(chan bool, 1)
go writeData(intChan)
go readData(intChan, exitChan)
//time.Sleep(time.Second * 10)
for {
_, ok := <-exitChan
if !ok {
break
}
}
}
运行结果
writeData 1
writeData 2
writeData 3
writeData 4
writeData 5
writeData 6
writeData 7
writeData 8
writeData 9
writeData 10
writeData 11
readData 读到数据=1
writeData 12
readData 读到数据=2
writeData 13
readData 读到数据=3
writeData 14
readData 读到数据=4
writeData 15
readData 读到数据=5
writeData 16
readData 读到数据=6
writeData 17
readData 读到数据=7
writeData 18
readData 读到数据=8
writeData 19
readData 读到数据=9
writeData 20
readData 读到数据=10
readData 读到数据=11
readData 读到数据=12
readData 读到数据=13
readData 读到数据=14
readData 读到数据=15
readData 读到数据=16
readData 读到数据=17
readData 读到数据=18
readData 读到数据=19
readData 读到数据=20
Q: 如果只写不读会发生什么情况?【阻塞deadlock】
如果只是向管道写入数据,而没有读取,就会出现阻塞而deadlock,原因是intChan容量
是10,而代码writeData会写入50个数据,因此会阻塞在writeData的ch<-i
如果写管道与读管道速率不一致,是否会发生阻塞?
不会,只要有读,到达越界的点会停止写入,等到读取完成有剩余空间后会再次进行写入。编译器会在底层维护上下文判定有没有读取,换句话说,只要有读,就不会报错。
参考:韩顺平go课程笔记