Middle
Pode-se usar o mesmo buffer []byte em várias goroutines?
sobes.tech IA
Resposta da IA
Sim, é possível, mas é necessário garantir a sincronização de acesso para evitar condições de corrida.
As abordagens mais comuns:
-
Mutex (
sync.Mutex) :import "sync" var buf []byte var mu sync.Mutex func processBuffer() { mu.Lock() defer mu.Unlock() // Acesso seguro a buf // Por exemplo: buf = append(buf, data...) } func main() { // Inicialização de buf go processBuffer() go processBuffer() // ... } -
Canais (
chan) :Pode-se transferir a propriedade do buffer entre goroutines ou usar um canal para coordenar o acesso.
import "bytes" type BufferAccess struct { buf *bytes.Buffer // Ponteiro para o buffer para uso compartilhado mu sync.Mutex // Mutex para sincronizar o acesso } func (ba *BufferAccess) Write(p []byte) (n int, err error) { ba.mu.Lock() defer ba.mu.Unlock() return ba.buf.Write(p) } func worker(ba *BufferAccess, data []byte) { ba.Write(data) // Escrita segura via método com mutex } func main() { sharedBuffer := &BufferAccess{buf: &bytes.Buffer{}} // Iniciar goroutines, passando sharedBuffer go worker(sharedBuffer, []byte("hello")) go worker(sharedBuffer, []byte("world")) // ... } -
Pool de buffers (
sync.Pool) :Menor necessidade de sincronização no acesso ao buffer em si, se cada goroutine obtém um buffer do pool, usa-o e depois o devolve.
import ( "bytes" "sync" ) var bufferPool = sync.Pool{ New: func() interface{} { // Tamanho padrão do buffer return bytes.NewBuffer(make([]byte, 0, 1024)) }, } func processData(data []byte) { buf := bufferPool.Get().(*bytes.Buffer) defer bufferPool.Put(buf) // É importante devolver o buffer ao pool buf.Reset() // Limpar o buffer antes de usar buf.Write(data) // Processar dados no buffer // ... } func main() { go processData([]byte("message1")) go processData([]byte("message2")) // ... }
Importante: O uso de buffer sem sincronização em ambiente concorrente levará a condições de corrida, o que pode causar comportamentos imprevisíveis e erros difíceis de detectar.