Sobes.tech
Middle+

Jak je bezpečné předávat slices do různých gorutin?

sobes.tech AI

Odpověď od AI

Předávat přímo slices do různých gorutin není bezpečné, pokud je gorutiny budou měnit současně bez synchronizace nebo pokud se slice mění v jedné gorutině po jeho předání (podle kopie hlavičky) do jiné.

Důvody nebezpečí:

  • Sdílené základní pole: Slices jsou hlavičky (ukazatel na základní pole, délka, kapacita), které ukazují na společné základní pole.
  • Race condition (závodní podmínka): Současný zápis do stejného prvku základního pole nebo změna jeho velikosti z různých gorutin povede ke závodní podmínce, nepředvídatelným výsledkům a chybám.

Bezpečné způsoby práce se slices v gorutinách:

  1. Předání kopie slices: Vytvořit úplnou kopii slices a předat ji. To je bezpečné, protože gorutiny pracují s oddělenými daty.

    // vytvoření úplné kopie slices
    newSlice := make([]int, len(originalSlice))
    copy(newSlice, originalSlice)
    
  2. Použití kanálů: Předávat prvky slices nebo samotný slice přes kanály. Kanály zajišťují synchronizaci a izolaci dat.

    // předání prvků přes kanál
    ch := make(chan int)
    go func() {
        for _, v := range originalSlice {
            ch <- v
        }
        close(ch)
    }()
    
    // předání slices přes kanál
    chSlice := make(chan []int)
    go func() {
        chSlice <- originalSlice // předání podle hlavičky, ale kanál synchronizuje
                                // důležité: neměnit originalSlice po odeslání
    }()
    
  3. Synchronizace pomocí sync.Mutex nebo sync.RWMutex: Ochránit přístup ke slices pomocí mutexů. To zajišťuje, že pouze jedna gorutina může měnit slice v jakémkoli okamžiku.

    import "sync"
    
    var mu sync.Mutex
    var sharedSlice []int
    
    func modifySlice(index, value int) {
        mu.Lock()
        defer mu.Unlock()
        if index < len(sharedSlice) {
            sharedSlice[index] = value
        }
    }
    

Porovnání přístupů:

Přístup Bezpečnost Výkon při velkých slices Složitost
Kopie slices Vysoká Nižší (kopírování dat) Jednoduchá
Kanály Vysoká Závisí (náklady operací kanálu) Střední
Mutexy Vysoká Vysoká (pokud nejsou silné konflikty) Střední

Tudíž předávání hlavičky slices do různých gorutin bez další synchronizace nebo kopírování není bezpečné. Je nutné použít některou z výše uvedených metod pro zajištění bezpečnosti dat.