记一个go 并发外部归并排序遇到的小经验
//读取数据
func ReaderSource(reader io.Reader,chunkSize int) <-chan int{
out := make(chan int)
//out := make(chan int,1024) //缓冲 优化效率
go func() {
buffer := make([]byte,8)
bytesread :=0
for{
n, err := reader.Read(buffer) //n 是上面 那个 buffer 8 字节
bytesread+=n
//fmt.Println(n,err)
if n>0{
v:=int(binary.BigEndian.Uint64(buffer))
out<-v
}
if err!=nil || (chunkSize!=-1 && bytesread>=chunkSize){
break
}
}
close(out)
}()
return out
}
func NetworkSource(addr string) <-chan int{
/*out:=make(chan int,0)
go func() {
conn, err := net.Dial("tcp", addr)
if err != nil {
panic(err)
}
defer conn.Close()
reader := bufio.NewReader(conn)
r:=ReaderSource(reader,-1)
for v:=range r{
out<-v
}
close(out)
}()
return out*/
//todo 直接这样竟然不行 find why!!!!!
// todo 为什么会直接 merge done 而没要预期的阻塞???????????????????
//TODO 然而上面的可以 ????
//todo !!!!基本确定了 应该是 defer close 的问题!!!!!!
conn, err := net.Dial("tcp", addr)
if err != nil {
panic(err)
}
//defer conn.Close()
reader := bufio.NewReader(conn)
out :=ReaderSource(reader,-1) //why dont use this, or can only this work
fmt.Println(out)
return out
}
上面两个基本的读取方法 NetworkSource 的第一段注释代码是正常代码 当时非常不解 为什么不能直接return ReaderSource(buffio.NewReader(conn), -1)呢? 就像第二段代码
conn, err := net.Dial("tcp", addr)
if err != nil {
panic(err)
}
defer conn.Close()
reader := bufio.NewReader(conn)
out :=ReaderSource(reader,-1) //why dont use this, or can only this work
fmt.Println(out)
return out
这样 而要去重新读取又生成一个out chan
尝试过后 发现解
注意上方连接的 defer close()了
如果直接return ReaderSource 连接会立马关闭掉 那整个ReaderSource相当于废了!
所以这里如果把defer close()去掉 那么 实际上也可以 直接return ReaderSource 但是连接应该被关闭呀 所以还是用了 go func + 辅助chan 来实现
Tags : 本文未设置标签
您可以自由的转载和修改,但请务必注明文章来源并且不可用于商业目的。
本站大部分内容收集于互联网,如果有侵权内容、不妥之处,请联系删除。敬请谅解!
已有 2 条评论