Maison >développement back-end >Golang >GO : manque de synchronisation

GO : manque de synchronisation

Linda Hamilton
Linda Hamiltonoriginal
2024-11-30 01:10:11586parcourir

GO:lack of synchronization

var a string
var done bool

func setup() {
    a = "hello, world"
    done = true
}

func doprint() {
    if !done {
        once.Do(setup)
    }
    print(a)
}

func twoprint() {
    go doprint()
    go doprint()
}

Analyse du code

Variables :

  • a et b sont des variables globales de type int, partagées par toutes les goroutines.

Fonctions :

  • f() :
    • Écrit dans a et b séquentiellement (a = 1 et b = 2).
  • g() :
  • Lit et imprime b suivi de a.

Concurrence dans main() :

  • La fonction f() est exécutée en tant que goroutine distincte en utilisant go f().
  • La fonction g() est exécutée directement dans la goroutine principale.

Problèmes potentiels :

  • La goroutine exécutant f() et la goroutine principale exécutant g() s'exécutent simultanément.
  • Les écritures sur a et b dans f() peuvent ne pas se terminer avant que g() ne lise et imprime les valeurs de a et b.
  • Cela introduit une course aux données, où l'accès simultané (écriture dans f() et lecture dans g()) se produit sur la mémoire partagée (a et b) sans synchronisation.

Résultats possibles
En raison du manque de synchronisation, la sortie du programme n'est pas déterministe. Voici les scénarios possibles :

Cas 1 : g() s'exécute avant que f() ne modifie a et b :

  • Les valeurs initiales de a et b sont 0 (par défaut pour les int non initialisés dans Go).
0
0

ou

CAS 2 : Si b = 2 est terminé avant g() mais que a = 1 ne l'est pas, le résultat pourrait être :

2
0

Observations clés
Course aux données : l'accès simultané à a et b sans synchronisation introduit une course aux données. Cela rend le comportement du programme indéfini et imprévisible

Correction du code

  1. Utilisation d'un sync.WaitGroup : Assurez-vous que f() se termine avant que g() s'exécute
var a, b int
var wg sync.WaitGroup

func f() {
    a = 1
    b = 2
    wg.Done()
}

func g() {
    print(b)
    print(a)
}

func main() {
    wg.Add(1)
    go f()
    wg.Wait()
    g()
}

  1. Utiliser les Canaux : Signaler quand f() est terminé :
var a, b int

func f(done chan bool) {
    a = 1
    b = 2
    done <- true
}

func g() {
    print(b)
    print(a)
}

func main() {
    done := make(chan bool)
    go f(done)
    <-done
    g()
}

Ici, g() attend que f() envoie un signal sur le canal terminé.

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!

Déclaration:
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