Maison > développement back-end > Golang > L'affectation de pointeurs est-elle atomique dans Go et comment peut-elle être sécurisée ?

L'affectation de pointeurs est-elle atomique dans Go et comment peut-elle être sécurisée ?

Linda Hamilton
Libérer: 2024-12-24 14:09:10
original
290 Les gens l'ont consulté

Is Pointer Assignment Atomic in Go, and How Can It Be Made Safe?

Attribution atomique de pointeurs dans Go

Go fournit une variété d'outils pour gérer la concurrence, mais une question qui se pose souvent est de savoir si l'attribution d'un pointeur est une opération atomique.

Opérations atomiques dans Go

Dans Go, les seules opérations dont le caractère atomique est garanti sont celles trouvées dans le package sync.atomic. En tant que tel, l'attribution d'un pointeur n'est pas nativement atomique.

Affectation sécurisée du pointeur

Pour attribuer un pointeur de manière atomique, vous avez deux options :

  1. Acquérir un verrou : L'utilisation d'un verrou (par exemple, sync.Mutex) garantit que une seule goroutine peut accéder au pointeur à la fois, évitant ainsi les conditions de concurrence.
  2. Utiliser les primitives atomiques : Le package sync.atomic propose des primitives atomiques comme atomic.StorePointer et atomic.LoadPointer, qui peuvent être utilisé pour attribuer et récupérer atomiquement des valeurs de pointeur.

Exemple avec Mutex

Voici un exemple utilisant un sync.Mutex pour protéger une affectation de pointeur :

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()
}
Copier après la connexion

Exemple avec des primitives atomiques

Alternativement , vous pouvez utiliser des primitives atomiques pour réaliser atomicité :

import "sync/atomic"
import "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))
}
Copier après la connexion

Considérations

  • L'utilisation de sync.atomic peut compliquer le code en raison de la nécessité de convertir en unsafe.Pointer.
  • Les verrous sont généralement considérés comme idiomatiques dans Go, alors que l'utilisation de primitives atomiques est déconseillé.
  • Une approche alternative consiste à utiliser une seule goroutine pour l'accès au pointeur et à communiquer les commandes via des canaux, ce qui correspond mieux au modèle de concurrence de Go.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal