Sobes.tech
Middle

Оё мумкин аст як буфер []byte-ро дар чанд горутин истифода бурд?

sobes.tech AI

Ҷавоб аз AI

ҳа, мумкин, аммо лозим аст, ки ҳамоҳангсозии дастрасиро таъмин кунед, то ки дар Data Raceҳо пешгирӣ шавад.

Роҳи маъмултарини:

  1. Мьютексҳо (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()
        // ...
    }
    
  2. Каналҳо (chan):

    Мумкин аст, ки ownership-ро дар байни goroutines интиқол диҳед ё барои ҳамоҳангсозии дастрасӣ канал истифода баред.

    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{}}
        // Иҷрои goroutines, интиқол додани sharedBuffer
        go worker(sharedBuffer, []byte("hello"))
        go worker(sharedBuffer, []byte("world"))
        // ...
    }
    
  3. Пулҳои буфер (sync.Pool):

    Камтар лозим аст, ки дастрасиро ба худи буфер ҳамоҳангсозӣ кунед, агар ҳар goroutine буферро аз пул бигирад, истифода барад ва сипас баргардонад.

    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 оварда мерасонад, ки ба рафтори номуайян ва хатоҳои душвор ошкор оварда мерасонад.