Middle
Бир нече goroutineда бирдей []byte буферин колдонуу мүмкүнбү?
sobes.tech AI
AIден жооп
ооба, мүмкүн, бирок маалыматтардын жарыштарын алдын алуу үчүн кирүү синхрондоштуруу камсыздалышы керек.
Эң кеңири колдонулган ыкмалар:
-
Мьютекс (
sync.Mutex):import "sync" var buf []byte var mu sync.Mutex func processBuffer() { mu.Lock() defer mu.Unlock() // Коопсуз кирүү buf // Мисалы: buf = append(buf, data...) } func main() { // bufду инициализациялоо go processBuffer() go processBuffer() // ... } -
Каналдар (
chan):Буштуруучу буфердин ээлик укугун горутиналар ортосунда өткөрүп берүү же канал аркылуу кирүү көзөмөлдөө.
import "bytes" type BufferAccess struct { buf *bytes.Buffer // Жалпы колдонуу үчүн буфердин көрсөткүчү mu sync.Mutex // Мьютекс кирүүнү синхрондоштуруу үчүн } 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) // Мьютекс менен коопсуз жазуу } func main() { sharedBuffer := &BufferAccess{buf: &bytes.Buffer{}} // Горутина иштетүү, sharedBuffer өткөрүү go worker(sharedBuffer, []byte("hello")) go worker(sharedBuffer, []byte("world")) // ... } -
Буферлердин пулу (
sync.Pool):Ар бир горутинанын пулдан буфер алганы, аны колдонгону жана кайра кайтарганы менен, буферге кирүүнү синхрондоштуруу керек эмес.
import ( "bytes" "sync" ) var bufferPool = sync.Pool{ New: func() interface{} { // Бууфердин алдын ала өлчөмү return bytes.NewBuffer(make([]byte, 0, 1024)) }, } func processData(data []byte) { buf := bufferPool.Get().(*bytes.Buffer) defer bufferPool.Put(buf) // Бууферди кайра пулга кайтаруу buf.Reset() // Колдонмого даярдоо үчүн тазалоо buf.Write(data) // Маалыматты иштетүү // ... } func main() { go processData([]byte("message1")) go processData([]byte("message2")) // ... }
Маанилүү: Конкуренттик чөйрөдө буферди синхрондоштурбастан колдонуу Data Race абалына алып келет, ал программа ишинин күтүүсүздөп жана кыйынчылык менен аныкталган каталарга себеп болот.