关于阻塞的情况,下面进行了总结:
没有缓冲区的管道:读没有缓冲区的管道会阻塞,直到有其他协程往当前管道里面写入数据。同理:写没有缓冲区的管道也会阻塞,直到有其他协程从当前管道读取数据。
有缓冲区的管道:读有缓冲区的管道,但是管道里面没有数据,这个时候也会阻塞,直到有协程往当前管道里面写入数据。同理,写有缓冲区的管道,但是管道是满的,这个时候也会阻塞,直到有协程从当前管道道里面读取数据。
上面的关于没有缓冲区的管道,为什么我会写其他协程,因为没有缓冲区的管道没办法在一个协程里面完成这个读写。但是有缓冲的管道,能够在同一个协程里面完成读写。
使用内置函数close()可以关闭管道,如果往关闭的管道里面写数据会发生panic,但是关闭的管道依然可以读。
从管道里面读数据可以有两种赋值方式
代码语言:javascript复制 v := <-ch
v, ok := <-ch
第一个变量是读出来的数据,第二个变量ok表示读取数据是否成功,第二个变量ok仅仅表示读取数据是否成功,如果管道关闭了,但是管道里面如果能够获取到数据依然能读取数据,ok也会返回true。
下面我们看一下例子:
代码语言:javascript复制package main
import "fmt"
func main() {
ch := make(chan int, 10)
ch <- 1
ch <- 2
r, ok := <-ch
fmt.Println("第一次:", r, ok)
close(ch)
r, ok = <-ch
fmt.Println("第二次:", r, ok)
r, ok = <-ch
fmt.Println("第三次:", r, ok)
}
执行结果如下:
代码语言:javascript复制第一次:1 true
第二次:2 true
第三次:0 false
管道实现了一种FIFO(先入先出)的队列,数据总是按照写入的顺序流出管道。
关于go的管道读数据总结,希望对大家有帮助,欢迎留言。