5
Ho bisogno di una funzione per aggiungere atomicamente valori float32 in Go. Questo è ciò che si avvicinò con base a un codice C che ho trovato:Vai atomic.AddFloat32()
package atomic
import (
"sync/atomic"
"unsafe"
"math"
)
func AddFloat32(addr *float32, delta float32) (new float32) {
unsafeAddr := (*uint32)(unsafe.Pointer(addr))
for {
oldValue := math.Float32bits(*addr)
new = *addr + delta
newValue := math.Float32bits(new)
if atomic.CompareAndSwapUint32(unsafeAddr, oldValue, newValue) {
return
}
}
}
dovrebbe funzionare (cioè davvero essere atomica)? C'è un modo migliore/più veloce per farlo in Go?
@JimB: Quando si dice che potrebbe non riuscire, vuoi dire che dipende l'architettura di destinazione? Il codice quotato di go/src/sync/atomic/64bit_arm.go è affidabile solo sul braccio? –
@B_old: scusate, mi sembra di aver sufficientemente confuso l'argomento qui. Sono d'accordo che l'esempio di @ peterSO è corretto e aggiorna correttamente il valore float32. Il commento che ho fatto riguardava solo il rilevatore di gare e il modo in cui * poteva * segnalare la lettura non protetta da '* addr', anche se al momento non lo è. Garantire che il codice passi sotto '-race' è spesso fondamentale, e se questo lo segnala in futuro, non è difficile da aggirare. (rimosso vecchi commenti, e non erano veramente utili) – JimB