英文:
Is the Go bytes.Buffer thread-safe?
问题
在Go编程语言中,bytes.Buffer
是线程安全的吗?据我所知,它的文档没有提到线程安全性。
英文:
In the Go programming language, is bytes.Buffer
thread-safe? AFAIK, its documentation does not mention thread safety.
答案1
得分: 32
不行。
Go的文档遵循一个简单的规则:如果没有明确说明对某个东西的并发访问是安全的,那就不是安全的。
英文:
No.
The Go documentation follows a simple rule: If it is not explicitly stated that concurrent access to something is safe, it is not.
答案2
得分: 21
不,但你可以很容易地将其封装在一个线程安全的结构体中!
对于简单的操作:
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()
}
然后像使用 var buf Buffer
一样使用它。
如果需要更多 bytes.Buffer
的功能,可以自由选择:
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()
}
// 其他方法省略...
这样可以确保在并发访问时的线程安全性。
英文:
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)
}
答案3
得分: 7
使用io.Pipe()
函数调用,它提供了一对连接的对象(*PipeReader
、*PipeWriter
)用于同步读写。这可以并行进行,并且是线程安全的。
英文:
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.
答案4
得分: 0
bytes.Buffer不是线程安全的,但是这里有一个使用"通道和通信"安全地向Buffer(或任何io.StringWriter)写入的示例。
type SyncWriter struct {
w io.StringWriter
finish sync.WaitGroup
queue chan string
err error
}
func NewSyncWriter(w io.StringWriter) *SyncWriter {
var t SyncWriter
t.w = w
t.queue = make(chan string, 5)
t.finish.Add(1)
go t.writer()
return &t
}
func (t *SyncWriter) Close() error {
close(t.queue)
t.finish.Wait()
return t.err
}
func (t *SyncWriter) WriteString(s string) (int, error) {
t.queue <- s
return len(s), nil
}
func (t *SyncWriter) Write(p []byte) (int, error) {
return t.WriteString(string(p))
}
func (t *SyncWriter) writer() {
defer t.finish.Done()
for s := range t.queue {
_, err := t.w.WriteString(s)
if err != nil && t.err == nil {
t.err = err
}
}
}
以下是如何使用它的示例:
func write(wg *sync.WaitGroup, w io.Writer, d int) {
fmt.Fprintf(w, "%d", d)
wg.Done()
}
func main() {
var buf bytes.Buffer
w := NewSyncWriter(&buf)
w.WriteString("hello ")
var wg sync.WaitGroup
wg.Add(10)
for i := 0; i < 10; i++ {
go write(&wg, w, i)
}
wg.Wait()
w.Close()
fmt.Printf("%s\n", buf.String())
}
英文:
bytes.Buffer is not thread safe, but here's an example of writing to a Buffer (or any io.StringWriter) safely using "channels and communication".
type SyncWriter struct {
w io.StringWriter
finish sync.WaitGroup
queue chan string
err error
}
func NewSyncWriter(w io.StringWriter) *SyncWriter {
var t SyncWriter
t.w = w
t.queue = make(chan string, 5)
t.finish.Add(1)
go t.writer()
return &t
}
func (t *SyncWriter) Close() error {
close(t.queue)
t.finish.Wait()
return t.err
}
func (t *SyncWriter) WriteString(s string) (int, error) {
t.queue <- s
return len(s), nil
}
func (t *SyncWriter) Write(p []byte) (int, error) {
return t.WriteString(string(p))
}
func (t *SyncWriter) writer() {
defer t.finish.Done()
for s := range t.queue {
_, err := t.w.WriteString(s)
if err != nil && t.err == nil {
t.err = err
}
}
}
And here's how to use it:
func write(wg *sync.WaitGroup, w io.Writer, d int) {
fmt.Fprintf(w, "%d", d)
wg.Done()
}
func main() {
var buf bytes.Buffer
w := NewSyncWriter(&buf)
w.WriteString("hello ")
var wg sync.WaitGroup
wg.Add(10)
for i := 0; i < 10; i++ {
go write(&wg, w, i)
}
wg.Wait()
w.Close()
fmt.Printf("%s\n", buf.String())
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论