Go 中的并发安全模板是一个关键问题,对于需要在并发环境下进行操作的程序来说,确保数据的安全性是至关重要的。在处理并发时,我们需要采取一些措施来保护共享资源,避免出现竞态条件和数据竞争。在这篇文章中,我将向大家介绍一些常用的并发安全模板,帮助你理解并发安全的概念,并提供一些实践中的建议。无论是初学者还是有经验的开发者,都可以从中受益。让我们一起来探讨如何在 Go 中实现并发安全!
我有以下电话:
import ( "text/template" ) //... template.new(filepath.base(name)).funcs(templatefunctions).parse(string(asset))
在多个 go 例程中同时调用, 这又会导致以下恐慌:
fatal error: concurrent map iteration and map write
这是回溯:
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
上的行
上面引用了。它是 template.new(...)
。
周围的函数是从 goroutine 中同时调用的。
这是来自 go/src/text/template/funcs.go:88
的代码是否有帮助:
// 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 } }
如果 template.new
是并发安全的,为什么这一行会产生这种恐慌,我应该如何正确处理它?
更新。
令人讨厌的函数loadembeddedtemplates
的代码:
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 }
该函数只是依次加载 share/templates/
中的所有模板share/templates/
中的所有模板
您的 loadEmbeddedTemplates()
函数访问 templateFunctions
变量,将其传递给 Template.Funcs()
loadEmbeddedTemplates()
函数访问 templateFunctions
变量,将其传递给 ,后者显然会读取它(将迭代它)。Template.Funcs()
以上是Go 中的并发安全模板:我该怎么做?的详细内容。更多信息请关注PHP中文网其他相关文章!