Parallelitätssichere Vorlagen in Go: Wie mache ich das?

WBOY
Freigeben: 2024-02-08 21:50:10
nach vorne
930 Leute haben es durchsucht

Go 中的并发安全模板:我该怎么做?

Parallelitätssicherheitsvorlagen in Go sind ein zentrales Thema. Für Programme, die in einer gleichzeitigen Umgebung ausgeführt werden müssen, ist die Gewährleistung der Datensicherheit von entscheidender Bedeutung. Beim Umgang mit Parallelität müssen wir einige Maßnahmen ergreifen, um gemeinsam genutzte Ressourcen zu schützen und Rennbedingungen und Datenwettläufe zu vermeiden. In diesem Artikel stelle ich Ihnen einige häufig verwendete Vorlagen für Parallelitätssicherheit vor, helfe Ihnen, das Konzept der Parallelitätssicherheit zu verstehen, und gebe einige praktische Vorschläge. Sowohl Anfänger als auch erfahrene Entwickler können davon profitieren. Lassen Sie uns untersuchen, wie Sie in Go! Parallelitätssicherheit erreichen können!

Frageinhalt

Ich habe folgende Telefonnummer:

import (
  "text/template"
)

//...

template.new(filepath.base(name)).funcs(templatefunctions).parse(string(asset))
Nach dem Login kopieren

Gleichzeitig in mehreren Go-Routinen anrufen, Dies wiederum führt zu folgender Panik:

fatal error: concurrent map iteration and map write
Nach dem Login kopieren

Das ist der Traceback:

goroutine 140 [running]:
text/template.addvaluefuncs(0xc00188e000?, 0xc00188e000?)
        [...]/go/src/text/template/funcs.go:88 +0x76
[...]/modules/template.loadembeddedtemplates({0x38ff6cb?, 0xc001cf8060?})
        [...]/src/modules/template/configbased.go:163 +0x749
Nach dem Login kopieren

src/modules/template/configbased.go:163 Zeilen an oben zitiert. Es ist template.new(...).

Die umgebenden Funktionen werden gleichzeitig von der Goroutine aufgerufen.

Hier ist der Code von go/src/text/template/funcs.go:88 Wenn es hilft:

// addvaluefuncs adds to values the functions in funcs, converting them to reflect.values.
func addvaluefuncs(out map[string]reflect.value, in funcmap) {
    for name, fn := range in {
        if !goodname(name) {
            panic(fmt.errorf("function name %q is not a valid identifier", name))
        }
        v := reflect.valueof(fn)
        if v.kind() != reflect.func {
            panic("value for " + name + " not a function")
        }
        if !goodfunc(v.type()) {
            panic(fmt.errorf("can't install method/function %q with %d results", name, v.type().numout()))
        }
        out[name] = v
    }
}
Nach dem Login kopieren

Wenn template.new parallelitätssicher ist, warum erzeugt diese Zeile dann diese Panik und wie sollte ich richtig damit umgehen? <​​/p>

Aktualisiert.

Code für die nervige Funktionloadembeddedtemplates:

func loadEmbeddedTemplates(templateFile string) (*template.Template, error) {
    var t *template.Template

    templateFile = filepath.Join("share", "templates", filepath.Base(templateFile))
    dir := filepath.Dir(templateFile)
    names := assets.GetAssetNames()

    // All templates except + the last one at the end
    filteredNames := []string{}

    for _, name := range names {
        if !strings.HasPrefix(name, dir+"/") || !strings.HasSuffix(name, ".tmpl") {
            continue
        }

        if name != templateFile {
            filteredNames = append(filteredNames, name)
        }
    }

    filteredNames = append(filteredNames, templateFile)

    for _, name := range filteredNames {
        asset, err := assets.GetAsset(name)
        if err != nil {
            return nil, err
        }

        if t == nil {
            t, err = template.New(filepath.Base(name)).Funcs(templateFunctions).Parse(string(asset))
        } else {
            t, err = t.New(filepath.Base(name)).Parse(string(asset))
        }

        if err != nil {
            return nil, err
        }
    }

    return t, nil
}
Nach dem Login kopieren

Diese Funktion lädt einfach alle Vorlagen in share/templates/ nacheinander. share/templates/ 中的所有模板

解决方法

您的 loadEmbeddedTemplates() 函数访问 templateFunctions 变量,将其传递给 Template.Funcs()

Problemumgehung

Ihre Funktion loadEmbeddedTemplates() greift auf die Variable templateFunctions zu. Übergeben Sie es an

, das es offensichtlich liest (wird darüber iterieren). Template.Funcs()

Und Sie könnten es gleichzeitig in einer anderen Goroutine auffüllen. Daher der Fehler beim gleichzeitigen Schreiben der Karte. Der Zugriff darauf muss synchronisiert werden. 🎜 🎜Wenn möglich, füllen Sie es aus, bevor Sie es verwenden (geben Sie es an 🎜 weiter). Auf diese Weise ist keine zusätzliche Synchronisierung oder Sperrung erforderlich (gleichzeitiges Nur-Lesen ist immer möglich). 🎜

Das obige ist der detaillierte Inhalt vonParallelitätssichere Vorlagen in Go: Wie mache ich das?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:stackoverflow.com
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!