5
Potrzebuję funkcji do atomicznego dodawania wartości float32 w Go. To właśnie wpadł na podstawie jakiegoś kodu C znalazłem:Go 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
}
}
}
powinno działać (to znaczy być naprawdę atomowy)? Czy istnieje lepszy/szybszy sposób na zrobienie tego w Go?
@JimB: Kiedy mówisz, może nie, masz na myśli, że to zależy od docelowa architektura? Czy cytowany kod z go/src/sync/atomic/64bit_arm.go jest niezawodny tylko na ramieniu? –
@B_old: Przepraszam, wydaje mi się, że wystarczająco pomieszałem ten temat tutaj. Zgadzam się, że przykład @ peterSO jest poprawny i odpowiednio zaktualizuje wartość float32. Komentarz, który napisałem, dotyczył właśnie detektora wyścigów i tego, jak * może * oznaczać niezabezpieczony odczyt z '* addr', chociaż obecnie nie jest. Zapewnienie, że kod przechodzi przez '-race' jest często krytyczne, a jeśli oznaczy to w przyszłości, nie jest to trudne do obejścia. (usunięto stare komentarze i nie były one naprawdę użyteczne) – JimB