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!
Ich habe folgende Telefonnummer:
import ( "text/template" ) //... template.new(filepath.base(name)).funcs(templatefunctions).parse(string(asset))
Gleichzeitig in mehreren Go-Routinen anrufen, Dies wiederum führt zu folgender Panik:
fatal error: concurrent map iteration and map write
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
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 } }
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 }
Diese Funktion lädt einfach alle Vorlagen in share/templates/
nacheinander. share/templates/
中的所有模板
您的 loadEmbeddedTemplates()
函数访问 templateFunctions
变量,将其传递给 Template.Funcs()
loadEmbeddedTemplates()
greift auf die Variable templateFunctions
zu. Übergeben Sie es an , das es offensichtlich liest (wird darüber iterieren). Template.Funcs()
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!