为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用互斥体字段创建结构的元素

如何使用互斥体字段创建结构的元素

Go
青春有我 2022-01-04 21:09:10
我有一个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}在这种情况下使用互斥锁的正确方法是什么?
查看完整描述

2 回答

?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

虽然您对 Volker 的指导的回答很好,但您可能需要考虑使用非默认值,http.Client以便您可以Timeout在发出请求的客户端上设置 a (这样您就不必担心自己处理超时了)。


查看完整回答
反对 回复 2022-01-04
?
慕工程0101907

TA贡献1887条经验 获得超5个赞

我遵循了沃尔克的建议,并使用了一个渠道来解决问题。


func Read(url string, timeout time.Duration) (res *Response) { 

    done := make(chan bool) // A channel

    resChan := make(chan *Response)


    go func() { 

        resChan <- Get(url) 

        done <- true    

    }()     

    select {    

        case <-done:

            res = &Response{}    

        case <-time.After(timeout):

            res = &Response{"Gateway timeout\n", 504} 

    }

    return

}

现在,不能同时写入 res。它将是超时或返回的值Get(url)。


查看完整回答
反对 回复 2022-01-04
  • 2 回答
  • 0 关注
  • 177 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信