Heim  >  Artikel  >  Backend-Entwicklung  >  Datenwettbewerbsanalyse globaler Variablen und lokaler Variablen von Golang-Funktionen

Datenwettbewerbsanalyse globaler Variablen und lokaler Variablen von Golang-Funktionen

WBOY
WBOYOriginal
2023-05-21 08:19:35818Durchsuche

Golang ist eine stark typisierte Programmiersprache mit den Merkmalen Effizienz, Einfachheit und Parallelität und wird daher nach und nach von immer mehr Entwicklern bevorzugt. Bei der Entwicklung von Golang sind globale Variablen und lokale Variablen von Funktionen häufig mit Datenwettbewerbsproblemen verbunden. In diesem Artikel wird das Datenwettbewerbsproblem globaler Variablen und lokaler Variablen in Golang-Funktionen aus der Perspektive der tatsächlichen Codierung analysiert.

1. Datenwettlauf globaler Variablen

Auf globale Golang-Variablen kann in allen Funktionen zugegriffen werden. Wenn also kein strenges Design und keine strenge Codierung durchgeführt werden, kann es leicht zu Datenwettläufen kommen .

Zum Beispiel definieren wir im folgenden Code eine globale Variable num und erhöhen sie in zwei verschiedenen Funktionen:

var num int = 0

func addNum1() {
    for i := 0; i < 1000; i++ {
        num += 1
    }
}

func addNum2() {
    for i := 0; i < 1000; i++ {
        num += 1
    }
}

Im obigen Code erhöhen beide Funktionen die globale Variable num, was zu Datenkonkurrenzproblemen führen kann. Ein Datenwettlauf tritt auf, wenn zwei oder mehr Threads gleichzeitig auf dieselbe gemeinsam genutzte Ressource zugreifen, während mindestens einer der Threads auf die Ressource schreibt, was zu undefiniertem Verhalten führt.

Die Möglichkeit, dieses Problem zu lösen, besteht darin, den Mutex-Typ im von Golang bereitgestellten Synchronisierungspaket zu verwenden. Mutex ist eine Mutex-Sperre. Nur der Thread, der die Sperre hält, kann auf gemeinsam genutzte Ressourcen zugreifen. Das Folgende ist der geänderte Code:

var num int = 0
var mutex sync.Mutex

func addNum1() {
    for i := 0; i < 1000; i++ {
        mutex.Lock()
        num += 1
        mutex.Unlock()
    }
}

func addNum2() {
    for i := 0; i < 1000; i++ {
        mutex.Lock()
        num += 1
        mutex.Unlock()
    }
}

Im oben geänderten Code implementieren wir den gegenseitig ausschließenden Zugriff auf die globale Variable num über Mutex und vermeiden so das Problem der Datenkonkurrenz.

2. Datenwettlauf um lokale Variablen

Lokale Variablen werden innerhalb einer Funktion definiert und können nur innerhalb dieser Funktion aufgerufen werden, sodass relativ wenige Datenwettlaufprobleme auftreten können . Bei der Verwendung lokaler Variablen müssen jedoch noch einige Probleme beachtet werden.

Im folgenden Code gibt die Funktion getRandStr beispielsweise eine zufällige Zeichenfolge mit einer Länge von 10 zurück:

import (
    "math/rand"
    "time"
)

func getRandStr() string {
    rand.Seed(time.Now().UnixNano())
    baseStr := "abcdefghijklmnopqrstuvwxyz0123456789"
    var randBytes []byte
    for i := 0; i < 10; i++ {
        randBytes = append(randBytes, baseStr[rand.Intn(len(baseStr))])
    }
    return string(randBytes)
}

Im obigen Code haben wir eine Zufallszahl A generiert Als Rückgabewert wird eine zufällige Zeichenfolge mit einer Länge von 10 Ziffern verwendet. Ein solcher Code scheint kein Datenkonkurrenzproblem zu haben, aber tatsächlich, wenn man bedenkt, dass sich die Parameter in rand.Seed(time.Now().UnixNano()) mit der Zeit ändern, wenn er in mehreren Goroutinen gleichzeitig aufgerufen wird Diese Funktion kann dazu führen, dass die Funktion dasselbe Ergebnis zurückgibt, was zu einem Rennproblem führt.

Um dieses Problem zu lösen, können wir rand.Seed(time.Now().UnixNano()) außerhalb der Funktion extrahieren und müssen es nur einmal aufrufen, wenn das Programm ausgeführt wird. Das Folgende ist der geänderte Code:

import (
    "math/rand"
    "time"
)

func init() {
    rand.Seed(time.Now().UnixNano())
}

func getRandStr() string {
    baseStr := "abcdefghijklmnopqrstuvwxyz0123456789"
    var randBytes []byte
    for i := 0; i < 10; i++ {
        randBytes = append(randBytes, baseStr[rand.Intn(len(baseStr))])
    }
    return string(randBytes)
}

Im oben geänderten Code rufen wir rand.Seed(time.Now().UnixNano()) nur einmal über die Init-Funktion auf, wodurch die Notwendigkeit vermieden wird Problem des Datenwettbewerbs, der durch den gleichzeitigen Aufruf dieser Funktion in mehreren Goroutinen verursacht wird.

3. Fazit

Das Obige ist die Analyse des Datenwettbewerbsproblems globaler Variablen und lokaler Variablen in Golang-Funktionen :

# 🎜🎜#
    Verwenden Sie beim Lesen und Schreiben globaler Variablen eine Mutex-Sperre, um einen sich gegenseitig ausschließenden Zugriff auf die globale Variable zu erreichen.
  1. Bitte beachten Sie bei der Verwendung lokaler Variablen, dass bei Verwendung des Zufallszahlengenerators außerhalb der Funktion eine Initialisierung erforderlich ist, um Datenkonkurrenzprobleme durch den gleichzeitigen Zugriff mehrerer Goroutinen zu vermeiden.
Durch Befolgen der oben genannten Prinzipien können wir Datenwettlaufprobleme in Golang-Funktionen vermeiden.

Das obige ist der detaillierte Inhalt vonDatenwettbewerbsanalyse globaler Variablen und lokaler Variablen von Golang-Funktionen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn