Is the Go bytes.Buffer thread-safe?

前端 未结 4 2109
小蘑菇
小蘑菇 2021-02-19 05:22

In the Go programming language, is bytes.Buffer thread-safe? AFAIK, its documentation does not mention thread safety.

相关标签:
4条回答
  • 2021-02-19 05:27

    No.

    The Go documentation follows a simple rule: If it is not explicitly stated that concurrent access to something is safe, it is not.

    0 讨论(0)
  • 2021-02-19 05:37

    No - but you can easily wrap it in a thread safe struct!

    For simple things:

    type Buffer struct {
        b bytes.Buffer
        m sync.Mutex
    }
    func (b *Buffer) Read(p []byte) (n int, err error) {
        b.m.Lock()
        defer b.m.Unlock()
        return b.b.Read(p)
    }
    func (b *Buffer) Write(p []byte) (n int, err error) {
        b.m.Lock()
        defer b.m.Unlock()
        return b.b.Write(p)
    }
    func (b *Buffer) String() string {
        b.m.Lock()
        defer b.m.Unlock()
        return b.b.String()
    }
    

    ..and use it as usual var buf Buffer, etc.

    Want more of bytes.Buffer? Feel free to cherry pick:

    func (b *Buffer) Bytes() []byte {
        b.m.Lock()
        defer b.m.Unlock()
        return b.b.Bytes()
    }
    func (b *Buffer) Cap() int {
        b.m.Lock()
        defer b.m.Unlock()
        return b.b.Cap()
    }
    func (b *Buffer) Grow(n int) {
        b.m.Lock()
        defer b.m.Unlock()
        b.b.Grow(n)
    }
    func (b *Buffer) Len() int {
        b.m.Lock()
        defer b.m.Unlock()
        return b.b.Len()
    }
    func (b *Buffer) Next(n int) []byte {
        b.m.Lock()
        defer b.m.Unlock()
        return b.b.Next(n)
    }
    func (b *Buffer) ReadByte() (c byte, err error) {
        b.m.Lock()
        defer b.m.Unlock()
        return b.b.ReadByte()
    }
    func (b *Buffer) ReadBytes(delim byte) (line []byte, err error) {
        b.m.Lock()
        defer b.m.Unlock()
        return b.b.ReadBytes(delim)
    }
    func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) {
        b.m.Lock()
        defer b.m.Unlock()
        return b.b.ReadFrom(r)
    }
    func (b *Buffer) ReadRune() (r rune, size int, err error) {
        b.m.Lock()
        defer b.m.Unlock()
        return b.b.ReadRune()
    }
    func (b *Buffer) ReadString(delim byte) (line string, err error) {
        b.m.Lock()
        defer b.m.Unlock()
        return b.b.ReadString(delim)
    }
    func (b *Buffer) Reset() {
        b.m.Lock()
        defer b.m.Unlock()
        b.b.Reset()
    }
    func (b *Buffer) Truncate(n int) {
        b.m.Lock()
        defer b.m.Unlock()
        b.b.Truncate(n)
    }
    func (b *Buffer) UnreadByte() error {
        b.m.Lock()
        defer b.m.Unlock()
        return b.b.UnreadByte()
    }
    func (b *Buffer) UnreadRune() error {
        b.m.Lock()
        defer b.m.Unlock()
        return b.b.UnreadRune()
    }
    func (b *Buffer) WriteByte(c byte) error {
        b.m.Lock()
        defer b.m.Unlock()
        return b.b.WriteByte(c)
    }
    func (b *Buffer) WriteRune(r rune) (n int, err error) {
        b.m.Lock()
        defer b.m.Unlock()
        return b.b.WriteRune(r)
    }
    func (b *Buffer) WriteString(s string) (n int, err error) {
        b.m.Lock()
        defer b.m.Unlock()
        return b.b.WriteString(s)
    }
    func (b *Buffer) WriteTo(w io.Writer) (n int64, err error) {
        b.m.Lock()
        defer b.m.Unlock()
        return b.b.WriteTo(w)
    }
    
    0 讨论(0)
  • 2021-02-19 05:38

    Unfortunatelly I didn't know about https://golang.org/pkg/io/#Pipe, so implemented this thing myself. Here it is: https://github.com/latitov/milkthisbuffer

    I understand that it is useless when there's standard io.Pipe thing, but just in case anyone is interested in how you may reinvent the bicycle, only to discover few hours later that you just did exactly that - invented the bicycle ))

    Besides, it's mutex/locks free.

    0 讨论(0)
  • 2021-02-19 05:53

    Use io.Pipe() function call which provide pair of connected objects (*PipeReader, *PipeWriter) for synchronous read/write. This could be done in parallel, and it's a thread-safe.

    0 讨论(0)
提交回复
热议问题