美文网首页
io.pipe 代码阅读

io.pipe 代码阅读

作者: wayyyy | 来源:发表于2022-04-18 05:04 被阅读0次
func main() {
    reader, writer := io.Pipe()

    go func() {
        writer.Write([]byte("hello world"))
        defer writer.Close()
    }()

    buffer := make([]byte, 9)
    reader.Read(buffer)
    fmt.Println(string(buffer))

    buffer2 := make([]byte, 10)
    reader.Read(buffer2)
    fmt.Println(string(buffer2))

    time.Sleep(time.Second * 2)

    buffer3 := make([]byte, 10)
    _, err := reader.Read(buffer3)
    if err != nil {
        fmt.Println(err.Error())
    }
    fmt.Println(string(buffer3))

    reader.Close()

    select {}
}

输出:


image.png
pipe 数据结构
type pipe struct {
    wrMu sync.Mutex // Serializes Write operations
    wrCh chan []byte
    rdCh chan int

    once sync.Once // Protects closing done
    done chan struct{}    // 用于事件通知,reader 关闭或者 writer 关闭。
    rerr onceError
    werr onceError
}

func Pipe() (*PipeReader, *PipeWriter) {
    p := &pipe{
        wrCh: make(chan []byte),
        rdCh: make(chan int),
        done: make(chan struct{}),
    }
    return &PipeReader{p}, &PipeWriter{p}
}

type PipeReader struct {
    p *pipe
}

type PipeWriter struct {
    p *pipe
}
pipeWriter
func (w *PipeWriter) Write(data []byte) (n int, err error) {
    return w.p.Write(data)
}

func (p *pipe) Write(b []byte) (n int, err error) {
    select {
    case <-p.done:
        return 0, p.writeCloseError()
    default:
        p.wrMu.Lock()          // 首先需要获取锁,保证多个 writer 的串行化
        defer p.wrMu.Unlock()
    }

    for once := true; once || len(b) > 0; once = false {
        select {
        case p.wrCh <- b:
            nw := <-p.rdCh  // write 之后,会在这里阻塞,直到收到reader 读取后通告过来的读取长度。
            b = b[nw:]
            n += nw
        case <-p.done:
            return n, p.writeCloseError()
        }
    }
    return n, nil
}
pipeReader
func (r *PipeReader) Read(data []byte) (n int, err error) {
    return r.p.Read(data)
}

func (p *pipe) Read(b []byte) (n int, err error) {
    select {
    case <-p.done:
        return 0, p.readCloseError()
    default:
    }

    select {
    case bw := <-p.wrCh:
        nr := copy(b, bw)
        p.rdCh <- nr
        return nr, nil
    case <-p.done:
        return 0, p.readCloseError()
    }
}

相关文章

  • io.pipe 代码阅读

    输出: pipe 数据结构 pipeWriter pipeReader

  • 理解golang io.Pipe

    golang的io包中,稍微有点儿晦涩的就是Pipe方法,今天我们就一起来看一看这个Pipe。 函数定义如下: f...

  • Go 使用 io.Pipe()

  • 阅读代码

    2018-05-06 阅读代码 通读代码,做好标记: 函数以及函数的功能。 每个变量的初始赋值。 每个在程序的各个...

  • 阅读代码

    今天想准备3D实验的训练数据集,但是之前看过的代码已经记不清了。这样的问题一直存在,别人的代码啃过之后以为懂了,过...

  • 阅读代码

    看代码是很让人头大的事情,尤其是篇幅很长,依赖关系复杂的时候。一般来说,编译器会通过各种方式理清代码的逻辑,比如不...

  • Mantle 源代码阅读笔记 一

    Mantle 源代码阅读笔记 一 Mantle 源代码阅读笔记 一

  • 阅读散记(1)

    《代码阅读方法与实践》(中文版)——第一章 导论 为什么要阅读代码? 将代码作为文献 了解代码的工作方式 维护代码...

  • Vue2源码阅读(一):响应式原理

    一、阅读准备 阅读Vue.js代码前,需要准备: 仓库代码,方便加注释和多段关键代码可以同时阅读 打包后未压缩的代...

  • flag 代码阅读

    读 mapillary 的 street viewer 代码。 读 sfm pipeline 的 viewer 代...

网友评论

      本文标题:io.pipe 代码阅读

      本文链接:https://www.haomeiwen.com/subject/qhsqxrtx.html