深入理解go的管道数据读写

2022-04-25 09:00:59 浏览数 (1)

关于阻塞的情况,下面进行了总结:

没有缓冲区的管道:读没有缓冲区的管道会阻塞,直到有其他协程往当前管道里面写入数据。同理:写没有缓冲区的管道也会阻塞,直到有其他协程从当前管道读取数据。

有缓冲区的管道:读有缓冲区的管道,但是管道里面没有数据,这个时候也会阻塞,直到有协程往当前管道里面写入数据。同理,写有缓冲区的管道,但是管道是满的,这个时候也会阻塞,直到有协程从当前管道道里面读取数据。

上面的关于没有缓冲区的管道,为什么我会写其他协程,因为没有缓冲区的管道没办法在一个协程里面完成这个读写。但是有缓冲的管道,能够在同一个协程里面完成读写。

使用内置函数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的管道读数据总结,希望对大家有帮助,欢迎留言。

0 人点赞