Middle
Може ли исти []byte бафер да се користи у више горутина?
sobes.tech АИ
Одговор од АИ
Da, može, ali je potrebno obezbediti sinhronizaciju pristupa kako bi se sprečile trke podataka.
Najčešći pristupi:
-
Muteksi (
sync.Mutex):import "sync" var buf []byte var mu sync.Mutex func processBuffer() { mu.Lock() defer mu.Unlock() // Siguran pristup buf // Na primer: buf = append(buf, data...) } func main() { // Inicijalizacija buf go processBuffer() go processBuffer() // ... } -
Kanal (
chan):Možete prenositi vlasništvo nad baferom između gorutina ili koristiti kanal za koordinaciju pristupa.
import "bytes" type BufferAccess struct { buf *bytes.Buffer // Pokazivač na bafer za zajedničko korišćenje mu sync.Mutex // Muteks za sinhronizaciju pristupa } 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) // Siguran zapis putem metode sa muteksom } func main() { sharedBuffer := &BufferAccess{buf: &bytes.Buffer{}} // Pokretanje gorutina, prosleđujući sharedBuffer go worker(sharedBuffer, []byte("hello")) go worker(sharedBuffer, []byte("world")) // ... } -
Pool bafera (
sync.Pool):Manje je potrebno sinhronizovati pristup samom baferu, ako svaka gorutina uzima bafer iz poola, koristi ga, a zatim vraća.
import ( "bytes" "sync" ) var bufferPool = sync.Pool{ New: func() interface{} { // Podrazumevana veličina bafera return bytes.NewBuffer(make([]byte, 0, 1024)) }, } func processData(data []byte) { buf := bufferPool.Get().(*bytes.Buffer) defer bufferPool.Put(buf) // Obavezno vratiti bafer u pool buf.Reset() // Očistiti bafer pre korišćenja buf.Write(data) // Obrada podataka u baferu // ... } func main() { go processData([]byte("message1")) go processData([]byte("message2")) // ... }
Važno: Korišćenje bafera bez sinhronizacije u konkurentnom okruženju dovodi do stanja trke podataka, što je uzrok nepredvidivom ponašanju programa i teže uočljivim greškama.