Maison >développement back-end >Golang >Comment lire en toute sécurité les données partagées des routines Parallel Go ?

Comment lire en toute sécurité les données partagées des routines Parallel Go ?

Barbara Streisand
Barbara Streisandoriginal
2025-01-02 14:31:39462parcourir

How to Safely Read Shared Data from Parallel Go Routines?

Lecture des valeurs à partir de données partagées dans des routines Go parallèles

Problème :

Dans Go, comment les données peuvent-elles être lues en toute sécurité à partir de threads séparés dans le calcul parallèle ? Plus précisément, comment les données peuvent-elles être collectées à partir des threads de travail sans compromettre l'intégrité des données ?

Scénario :

Le thread principal crée plusieurs instances de travail qui s'exécutent de manière asynchrone. Toutes les 10 secondes, le thread principal doit collecter des valeurs (par exemple, le nombre d'itérations) auprès des travailleurs et afficher un rapport consolidé.

Question :

Est-il sécuritaire de lire directement les valeurs des travailleurs ? De plus, existe-t-il des approches alternatives pour mettre en œuvre efficacement cette exigence ?

Réponse :

La lecture directe des valeurs des travailleurs est dangereuse car elle viole le modèle de concurrence de Go. Dans Go, les données partagées entre les goroutines doivent être protégées par des mécanismes de synchronisation pour empêcher la corruption des données due à des opérations d'écriture simultanées.

Pour résoudre ce problème, une approche consiste à utiliser la structure de données sync.RWMutex :

  • Verrous en écriture : acquis par les travailleurs lors de la modification des données partagées, garantissant l'exclusivité accès.
  • Verrous de lecture : acquis par le thread principal lors de la lecture de données partagées, permettant des lectures simultanées mais empêchant les écritures.

Exemple d'implémentation utilisant sync.RWMutex :

type Worker struct {
    iterMu sync.RWMutex
    iter   int
}

func (w *Worker) Iter() int {
    w.iterMu.RLock()
    defer w.iterMu.RUnlock()
    return w.iter
}

func (w *Worker) setIter(n int) {
    w.iterMu.Lock()
    w.iter = n
    w.iterMu.Unlock()
}

Alternativement, le package sync/atomic propose des opérations atomiques qui garantissent un accès sécurisé aux threads partagés. variables. Exemple d'implémentation utilisant sync/atomic :

type Worker struct {
    iter int64
}

func (w *Worker) Iter() int64 {
    return atomic.LoadInt64(&w.iter)
}

func (w *Worker) setIter(n int64) {
    atomic.StoreInt64(&w.iter, n)
}

En utilisant ces méthodes, les deux approches fournissent une solution robuste pour lire les valeurs de threads séparés tout en préservant l'intégrité des données.

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