我有一个Get()功能:
func Get(url string) *Response {
res, err := http.Get(url)
if err != nil {
return &Response{}
}
// res.Body != nil when err == nil
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Fatalf("ReadAll: %v", err)
}
reflect.TypeOf(body)
return &Response{sync.Mutex(),string(body), res.StatusCode}
}
以及一个Read()函数:
func Read(url string, timeout time.Duration) (res *Response) {
done := make(chan bool)
go func() {
res = Get(url)
done <- true
}()
select { // As soon as either
case <-done: // done is sent on the channel or
case <-time.After(timeout): // timeout
res = &Response{"Gateway timeout\n", 504}
}
return
}
Response函数返回的类型定义为:
type Response struct {
Body string
StatusCode int
}
这个读取函数利用了Get()函数,也实现了超时。的问题是,如果发生超时和可发生数据争Get()响应被写入res在相同的时间Read()。
我有一个如何解决这个问题的计划。就是使用互斥锁。为此,我将向Response结构中添加一个字段:
type Response struct {
mu sync.Mutex
Body string
StatusCode int
}
以便Response可以锁定。但是,我不确定如何在代码的其他部分解决这个问题。
对于 Get(),我的尝试如下所示:
func Get(url string) *Response {
res, err := http.Get(url)
if err != nil {
return &Response{}
}
// res.Body != nil when err == nil
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Fatalf("ReadAll: %v", err)
}
reflect.TypeOf(body)
return &Response{sync.Mutex(),string(body), res.StatusCode} // This line is changed.
}
对于Read():
func Read(url string, timeout time.Duration) (res *Response) {
done := make(chan bool)
res = &Response{sync.Mutex()} // this line has been added
go func() {
res = Get(url)
done <- true
}()
select {
case <-done:
case <-time.After(timeout):
res.mu.Lock()
res = &Response{sync.Mutex(), "Gateway timeout\n", 504} // And mutex was added here.
}
defer res.mu.Unlock()
return
}
在这种情况下使用互斥锁的正确方法是什么?
慕无忌1623718
慕工程0101907
相关分类