Die einzigen Dinge, die garantiert atomar sind, sind die Operationen in sync.atomic.
Also, wenn Sie sicher sein wollen, müssen Sie entweder eine Sperre nehmen, zB sync.Mutex oder eines der atomaren Primitiven verwenden. Ich empfehle jedoch nicht, die atomaren Primitiven zu verwenden, da Sie sie überall verwenden müssen, wo Sie den Zeiger verwenden, und sie sind schwer zu bekommen.
den Mutex zu verwenden ist OK Go-Stil - Sie eine Funktion definieren, könnten den aktuellen Zeiger mit Verriegelungs sehr leicht, zum Beispiel so etwas wie
import "sync"
var secretPointer *int
var pointerLock sync.Mutex
func CurrentPointer() *int {
pointerLock.Lock()
defer pointerLock.Unlock()
return secretPointer
}
func SetPointer(p *int) {
pointerLock.Lock()
secretPointer = p
pointerLock.Unlock()
}
Diese Funktionen geben eine Kopie des Zeigers an ihren Kunden zurück die konstant bleiben, auch wenn der Master-Zeiger geändert wird. Dies kann oder kann nicht akzeptabel sein, abhängig davon, wie zeitkritisch Ihre Anforderung ist. Es sollte ausreichen, um ein undefiniertes Verhalten zu vermeiden - der Garbage Collector stellt sicher, dass die Zeiger immer gültig sind, selbst wenn der Speicher, auf den verwiesen wird, nicht mehr von Ihrem Programm verwendet wird.
Ein alternativer Ansatz wäre, nur den Zeiger Zugriff von einer Routine zu tun und Kanäle zu verwenden, die Routine in Dinge tun gehen. Das wäre idiomatischer zu gehen, aber möglicherweise nicht genau Ihre Anwendung.
aktualisieren
Here is an example zeigt, wie atomic.SetPointer
zu verwenden. Es ist ziemlich hässlich aufgrund der Verwendung von unsafe.Pointer
. Jedoch kompiliert unsafe.Pointer
Umwandlungen zu nichts, so dass die Laufzeitkosten gering sind.
import (
"fmt"
"sync/atomic"
"unsafe"
)
type Struct struct {
p unsafe.Pointer // some pointer
}
func main() {
data := 1
info := Struct{p: unsafe.Pointer(&data)}
fmt.Printf("info is %d\n", *(*int)(info.p))
otherData := 2
atomic.StorePointer(&info.p, unsafe.Pointer(&otherData))
fmt.Printf("info is %d\n", *(*int)(info.p))
}
Vielleicht finden Sie [dieses Thema] (https://groups.google.com/d/msg/golang-nuts/ueSvaEKgyLY/ZW_74IC4PekJ) interessant. – kostix
Sie können das Dokument ["Go memory model"] (http://golang.org/ref/mem) auch amüsant finden - es definiert die Anforderungen für Go-Implementierungen. AFAIK, es sagt nichts über die Atomität der Lade-/Speicheroperationen von primitiven Typen aus, sondern spricht nur über die beobachtbare Anordnung von ihnen. – kostix