Middle
Kas võib kasutada sama []byte buferit mitmes goroutine'is?
sobes.tech AI
Vastus AI-lt
Jah, see on võimalik, kuid on vaja tagada juurdepääsu sünkroniseerimine, et vältida andmelõngaid.
Kõige levinumad lähenemised:
-
Muteksid (
sync.Mutex):import "sync" var buf []byte var mu sync.Mutex func processBuffer() { mu.Lock() defer mu.Unlock() // Turvaline juurdepääs buf-ile // Näiteks: buf = append(buf, data...) } func main() { // Buf initsialiseerimine go processBuffer() go processBuffer() // ... } -
Kanali (
chan):Võite edastada omandiõiguse buferi vahel gorutinite või kasutada kanalit juurdepääsu koordineerimiseks.
import "bytes" type BufferAccess struct { buf *bytes.Buffer // Ühiselt kasutatav bufer mu sync.Mutex // Muteks juurdepääsu sünkroniseerimiseks } 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) // Turvaline kirjutamine muteksi abil } func main() { sharedBuffer := &BufferAccess{buf: &bytes.Buffer{}} // Gorutinite käivitamine, edastades sharedBuffer go worker(sharedBuffer, []byte("hello")) go worker(sharedBuffer, []byte("world")) // ... } -
Buferi bassein (
sync.Pool):Vähem on vaja sünkroniseerida juurdepääsu buferile, kui iga gorutin võtab buferi basseinist, kasutab seda ja tagastab tagasi.
import ( "bytes" "sync" ) var bufferPool = sync.Pool{ New: func() interface{} { // Vaikimisi buferi suurus return bytes.NewBuffer(make([]byte, 0, 1024)) }, } func processData(data []byte) { buf := bufferPool.Get().(*bytes.Buffer) defer bufferPool.Put(buf) // Vajalik buferi tagastamine basseinile buf.Reset() // Puhastada bufer enne kasutamist buf.Write(data) // Andmete töötlemine buferis // ... } func main() { go processData([]byte("message1")) go processData([]byte("message2")) // ... }
Oluline: Buferi kasutamine ilma sünkroniseerimiseta konkurentsikeskkonnas põhjustab andmelõngad, mis viivad ettearvamatu käitumise ja keeruliselt avastatavate vigadeni.