Maison > développement back-end > Golang > Le remplacement d'une variable mappée par un nouvel objet mappé est-il thread-safe ?

Le remplacement d'une variable mappée par un nouvel objet mappé est-il thread-safe ?

WBOY
Libérer: 2024-02-10 16:33:12
avant
912 Les gens l'ont consulté

Le remplacement dune variable mappée par un nouvel objet mappé est-il thread-safe ?

Éditeur PHP Apple est là pour répondre à une question courante : « Est-il thread-safe de remplacer une variable de mappage par un nouvel objet de mappage ? » Une variable de mappage est une structure de données courante utilisée pour stocker des paires clé-valeur. Dans un environnement multithread, la sécurité des threads est une considération importante. Bien que l'utilisation d'un nouvel objet de mappage puisse éviter le problème de l'accès simultané, sa compatibilité avec les threads doit encore être évaluée au cas par cas. Ensuite, nous explorerons cette question en profondeur pour aider les lecteurs à mieux comprendre la relation entre la sécurité des threads et les objets mappés.

Contenu de la question

Je ne pense pas qu'il soit thread-safe car l'objet mappé est plus grand que les mots machine et golang ne garantit pas qu'il est thread-safe. Mais lorsque j'exécute le code de démonstration en utilisant go run -race main.go, il ne signale jamais d'erreur. C'est peut-être la raison pour laquelle threadsanitizer s'appuie sur des contrôles d'exécution et des opérations d'affectation pour avoir du mal à satisfaire des conditions non sécurisées pour les threads.

Voici l'exemple de code :

package main

import (
    "fmt"
)

var m = make(map[int]bool)

func Read() {
    for {
        for k := range m {
            fmt.Println(k)
        }
    }
}

func Replace() {
    for {
        newM := make(map[int]bool, 10)
        for i := 0; i < 10; i++ {
            newM[i] = false
        }
        m = newM
    }
}

func main() {
    c := make(chan struct{})

    go Read()
    go Replace()

    <-c
}

Copier après la connexion

Alors, comment modifier le code pour déclencher des erreurs de concurrence ? Ou peut-être que je me trompe et que le code est thread-safe ?

Solution

Voici quelques points à noter :

for k := range m {
Copier après la connexion

Les expressions Range sont évaluées une fois au début de la boucle for. Cette opération lira donc m 一次(注意,这意味着如果循环中的代码重新分配 m ,则循环将继续迭代原始 m ,但是如果添加新元素或从 m 中删除元素,这些将被检测到循环),循环本身会调用 fmt.println , ce qui consommera la majeure partie du temps d'exécution dans cette goroutine. Si vous souhaitez rattraper le jeu, supprimez-le.

Deuxièmement, vous n'avez pas réellement besoin d'initialiser la deuxième carte.

Lorsque vous effectuez ces opérations et exécutez le détecteur de course, il peut détecter des courses de données. En ce qui me concerne, c'est le cas.

Le détecteur de conflits se plaindra d'un conflit lorsqu'il le détectera. Donc, s’il signale une correspondance, alors il y a une correspondance. Si ce n’est pas signalé, cela ne veut pas dire qu’il n’y a pas de contestation.

Sur ma plateforme, la variable map elle-même a en fait la même taille qu'un mot machine : c'est juste un pointeur vers la structure mappée. Par conséquent, les écritures sur les variables mappées sont effectivement atomiques, c'est-à-dire que vous ne verrez pas de mappages partiellement alloués sur cette plateforme. Cependant, cela n'empêche pas les conflits puisqu'il n'y a aucune garantie quand d'autres goroutines verront cette mémoire écrire.

En bref, c’est une compétition. Cela n'est pas dû à la taille de la variable map. Pour résoudre ce problème, utilisez un mutex.

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!

Étiquettes associées:
source:stackoverflow.com
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal