首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Go http包中提供共享结构?

如何在Go http包中提供共享结构?
EN

Stack Overflow用户
提问于 2017-08-25 17:05:37
回答 1查看 81关注 0票数 2

我有一个包含许多字段的结构(其中一些字段也是指向其他结构的指针),这些字段在单独的goroutine中不断更新。当提供页面时,从go的http模板访问相同的结构。

代码示例:

代码语言:javascript
复制
type SharedStruct struct {
     Description string
     Counter int
     Status_ *Status
     LastChecked time.Time
     //other fields
} 
var shared = &SharedStruct{}

go func() {
    //..updates fields every 5 minutes
}()

go-http处理程序:

代码语言:javascript
复制
func someHandler(w http.ResponseWriter, r *http.Request) {
   t.ExecuteTemplate(w, "page.html", shared)
}

page.html模板:

代码语言:javascript
复制
...
Status: {{.Status_.StatusCode}}
Counter: {{.Counter}}
Last checked: {{.LastChecked.Format "2006-02-01 15:04:05"}}

到目前为止,一切都像预期的那样工作,但我意识到,如果没有任何同步,可能会发生不好的事情。正确处理此问题的首选方法是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-25 17:15:04

首选方法与任何其他情况下相同。

或者在读取/更新共享结构时使用互斥:

代码语言:javascript
复制
var shared = &SharedStruct{}
var mux = &sync.RWMutex{}

func someHandler(w http.ResponseWriter, r *http.Request) {
    mux.RLock()
    defer mux.RUnlock()
    t.ExecuteTemplate(w, "page.html", shared)
}

// Code that modifies shared:
mux.Lock()
shared.Counter++
mux.Unlock()

或者,如果模板执行花费了很长时间,则可以复制shared结构并在执行模板时传递该副本,以便在模板执行期间不会阻止对shared的访问。请注意,在制作副本时,您仍然必须使用互斥锁。此外,如果不仅指针,而且指向的值可能会发生变化,您还必须复制这些值:

代码语言:javascript
复制
func someHandler(w http.ResponseWriter, r *http.Request) {
    mux.RLock()
    shared2 := &SharedStruct{}
    *shared2 = *shared
    shared2.Status_ = new(Status)
    *shared2.Status_ = *shared.Status_
    mux.RUnlock()

    t.ExecuteTemplate(w, "page.html", shared2)
}

如果模板只使用shared字段的一小部分,那么只复制这些字段就足够了。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45877980

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档