2015-04-07 9 views
10

È sicuro accedere a membri di diverse strutture da diverse goroutine?È thread-safe accedere a diversi membri di struct in go?

ho capito che scrivere alla stessa variabile senza sincronizzazione è dangareous:

package main 

type Apple struct { 
    color string 
    size uint 
} 

func main() { 
    apple := &Apple{} 
    go func() { 
     apple.color = "red" 
    }() 
    go func() { 
     apple.color = "green" 
    }() 
} 

ma si può scrivere a diversi membri struct senza alcun tipo di sincronizzazione?

package main 

type Apple struct { 
    color string 
    size uint 
} 

func main() { 
    apple := &Apple{} 
    go func() { 
     apple.color = "red" 
    }() 
    go func() { 
     apple.size = 42 
    }() 
} 

o dovrei usare chan o sync.Mutex per questo?

risposta

11

È necessario accedere in modo sicuro a variabili diverse da thread diversi e i membri della struttura sono variabili diverse. Quindi sì, dovrebbe essere sicuro.

Tuttavia, potrebbe non essere veloce. Le variabili che sono vicine nella memoria come membri struct condivideranno una linea cache della CPU. Una linea di cache è il più piccolo pezzo di memoria che una CPU (beh, la maggior parte dei modelli attuali) può bloccare. Ciò significa che CPU-2 deve attendere per scrivere fino a quando CPU-1 ha finito con quella linea di cache anche se stanno scrivendo su variabili diverse.

Non è sicuro cambiare il puntatore alla struct mentre si scrive alla struct da diversi thread. Nel tuo esempio se avevi una terza goroutine che faceva apple = &Apple{}, alcune delle altre goroutine in altri thread potevano scrivere sulla vecchia Apple o sulla nuova Apple e non sapresti.

+3

I paragrafi 1 e 3 sono eccezionali; il paragrafo 2 sembra off-topic (perché la preoccupazione è la sicurezza) e un cattivo consiglio (perché Go è un linguaggio di così alto livello, dovresti scrivere il codice più espressivo di default e ottimizzare dove necessario, caso per caso-- non applicando questa logica in generale, non c'è alcuna garanzia che queste goroutine vengano eseguite anche da diverse CPU!). – weberc2

+0

Accetto con @ weberc2. Mentre la condivisione falsa è una preoccupazione, la domanda riguarda la modifica di 2 variabili con o senza mutex. Il problema della linea cache deve essere presente indipendentemente dalla risposta corretta, e la soluzione sarebbe la stessa a prescindere. – JimB

+0

@ weberc2: Divertente, perché uno dei motivi per cui mi piace Go è perché non è un linguaggio di così alto livello. Compila molto come C con la garbage collection. –

Problemi correlati