package main
import("fmt""os")funcmain(){
ch1,ch2 :=make(chanint,3),make(chanint)gofunc(){
v, ok, s :=0,false,""for{select{case v, ok =<- ch1:
s ="a"case v, ok =<- ch2:
s ="b"}if ok {
fmt.Println("v&s",v, s)}else{
os.Exit(1)}}}()for i:=1; i <4; i++{select{case ch1 <- i:case ch2 <- i:}}
fmt.Println("send over")close(ch1)close(ch2)
fmt.Println("ch",ch1,ch2)select{}// 阻塞进程}
这里的
ok
是说c
是否关闭,因为关闭之后从chan种读取数据会立即返回。@justay 问题是我的channel 没有全部接收完毕啊, chan怎么会被关闭那? 这是完整代码
i存入的channel可能是ch1 或 ch2
存入的值可能是:
ch1 : 1
ch2 : 2、3、4
在goroutine里select对准备就绪channel进行随机读取
所以存在这样的读取可能 第1、2次都是读到的ch1,所以就打印出1,第二次读到ch1,因为已经关闭,直接退出
去掉缓存后,是同步读写,channel的两端有一端未准备好,另一端也不会执行相应的操作,类似于对i的输出进行了串行化处理,所以i会打印出1、2、3、4然后退出
利用
select
对chan
进行操作是随机选取chan
的。无论是往里面写数据或是读数据。这段会导致ch1,ch2里面的内容[1,2,3]是随机分布的。
这段读的顺序也是随机的,随机从
ch1
,ch2
里读取数据。想判断的话不要用同一个变量, 分别用不同的ok
变量则可以避免你的问题.你这么改一下:
case v1, ok1 = <- ch1:
等号钱加上冒号:case v1, ok1 := <- ch1:
@fuhuizn @justay @lee_ 谢谢各位我懂啦,因为随机发送到的chan不一样第一次正常,第二次可能某个通道已经关闭了 ok是false 所以才会退出, 谢谢各位