golang从channel读数据的各种情况⽂章⽬录
⽤var定义channel且不make
wg := sync.WaitGroup{}
var ch chan string
read :=func(){
fmt.Println("reading")
s :=<-ch
fmt.Println("read:", s)
wg.Done()
}
write :=func(){
fmt.Println("writing")
s :="t"
ch <- s
fmt.Println("write:", s)
wg.Done()
}
wg.Add(2)
go read()
go write()
fmt.Println("waiting")
wg.Wait()
输出:
waiting
writing
reading
fatal error: all goroutines are asleep - deadlock!
这种情况并不是报错空指针,⽽是死锁。加上make看看
⽤var定义channel且make
wg := sync.WaitGroup{}
var ch =make(chan string)
read :=func(){
fmt.Println("reading")
s :=<-ch
fmt.Println("read:", s)
wg.Done()
}
write :=func(){
fmt.Println("writing")
s :="t"
ch <- s
fmt.Println("write:", s)
wg.Done()
}
wg.Add(2)
go read()
go write()
输出
waiting
writing
reading
read: t
write: t
这种情况没什么⽑病,之所以先输出的read,是因为IO机制。下⾯给写加上for 直给写操作加for
wg := sync.WaitGroup{}
var ch =make(chan string)
read :=func(){
fmt.Println("reading")
s :=<-ch
fmt.Println("read:", s)
wg.Done()
}
write :=func(){
for{
fmt.Println("writing")
s :="t"
ch <- s
fmt.Println("write:", s)
}
wg.Done()
}
wg.Add(2)
go read()
go write()
fmt.Println("waiting")
wg.Wait()
write的返回值fmt.Println("finish")
输出
waiting
reading
writing
write: t
writing
read: t
fatal error: all goroutines are asleep - deadlock!
报错说所有的协程都睡着,意思就是runtime发现没有能拿来调度的协程了,报错退出。如果是在⼤项⽬中,这⾥则会阻塞,runtime会调度其他可运⾏的协程。下⾯把for移到读操作上。
直给读操作加for
wg := sync.WaitGroup{}
var ch =make(chan string)
read :=func(){
for{
fmt.Println("reading")
s :=<-ch
fmt.Println("read:", s)
}
wg.Done()
}
write :=func(){
fmt.Println("writing")
s :="t"
ch <- s
fmt.Println("write:", s)
wg.Done()
}
wg.Add(2)
go read()
go write()
fmt.Println("waiting")
wg.Wait()
fmt.Println("finish")
输出
waiting
reading
writing
write: t
read: t
reading
fatal error: all goroutines are asleep - deadlock!
跟上⾯现象基本⼀样,不再赘述,然后给俩操作都加上for
读写都加for
fmt.Println("reading")
s :=<-ch
fmt.Println("read:", s)
}
wg.Done()
}
write :=func(){
for{
fmt.Println("writing")
s :="t"
ch <- s
fmt.Println("write:", s)
}
wg.Done()
}
wg.Add(2)
go read()
go write()
fmt.Println("waiting")
wg.Wait()
fmt.Println("finish")
输出
waiting
writing
reading
read: t
write: t
writing
reading
read: t
reading
write: t
writing
write: t
writing
...
结果当然就是死循环了,这个很好理解。接下来才是本⽂的重点:读数据的第⼆个参数。我们先保持其他的都不动,在读的时候接收第⼆个返回值。
读channel的第⼆个返回值
fmt.Println("reading")
s, ok :=<-ch
fmt.Println("read:", s, ok)
}
wg.Done()
}
write :=func(){
for{
fmt.Println("writing")
s :="t"
ch <- s
fmt.Println("write:", s)
}
wg.Done()
}
wg.Add(2)
go read()
go write()
fmt.Println("waiting")
wg.Wait()
fmt.Println("finish")
输出
waiting
writing
reading
read: t true
reading
write: t
writing
write: t
writing
read: t true
reading
read: t true
reading
write: t
...
可以看出来,这第⼆个返回值是个bool类型,⽬前全都是true。那么什么时候会是false呢,把channel关上试试。为了更直观,把字符串的长度⼀起输出
关闭channel继续读

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。