Middle
Vai ir iespējams izmantot to pašu []byte buferi vairākās goroutine'ās?
sobes.tech AI
Atbilde no AI
Jā, tas ir iespējams, bet ir nepieciešams nodrošināt piekļuves sinhronizāciju, lai novērstu datu sacensības.
Visbiežāk izmantotie pieejas veidi:
-
Mutekši (
sync.Mutex):import "sync" var buf []byte var mu sync.Mutex func processBuffer() { mu.Lock() defer mu.Unlock() // Droša pieeja buf // Piemēram: buf = append(buf, data...) } func main() { // Buf inicializācija go processBuffer() go processBuffer() // ... } -
Kanāli (
chan):Var pārsūtīt īpašumtiesības uz buferi starp gorutīnām vai izmantot kanālu piekļuves koordinācijai.
import "bytes" type BufferAccess struct { buf *bytes.Buffer // Koplietošanas buferis mu sync.Mutex // Mutekss piekļuves sinhronizācijai } 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) // Droša rakstīšana ar muteksa palīdzību } func main() { sharedBuffer := &BufferAccess{buf: &bytes.Buffer{}} // Gorutīnu palaišana, nododot sharedBuffer go worker(sharedBuffer, []byte("hello")) go worker(sharedBuffer, []byte("world")) // ... } -
Buferu baseins (
sync.Pool):Mazāk nepieciešama piekļuves sinhronizācija pie paša bufera, ja katra gorutina ņem buferi no baseina, izmanto to un atgriež atpakaļ.
import ( "bytes" "sync" ) var bufferPool = sync.Pool{ New: func() interface{} { // Noklusējuma bufera izmērs return bytes.NewBuffer(make([]byte, 0, 1024)) }, } func processData(data []byte) { buf := bufferPool.Get().(*bytes.Buffer) defer bufferPool.Put(buf) // Obligāti atgriezt buferi baseinā buf.Reset() // Notīrīt buferi pirms lietošanas buf.Write(data) // Datu apstrāde buferī // ... } func main() { go processData([]byte("message1")) go processData([]byte("message2")) // ... }
Svarīgi: Bufera izmantošana bez sinhronizācijas konkurenču vidē novedīs pie datu sacensībām, kas izraisa nenoteiktu uzvedību un grūti diagnosticējamas kļūdas.