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

我有一个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

}


在这种情况下使用互斥锁的正确方法是什么?


青春有我
浏览 178回答 2
2回答

慕无忌1623718

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

慕工程0101907

我遵循了沃尔克的建议,并使用了一个渠道来解决问题。func Read(url string, timeout time.Duration) (res *Response) {&nbsp;&nbsp; &nbsp; done := make(chan bool) // A channel&nbsp; &nbsp; resChan := make(chan *Response)&nbsp; &nbsp; go func() {&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; resChan <- Get(url)&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; done <- true&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; }()&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; select {&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; case <-done:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res = &Response{}&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; case <-time.After(timeout):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res = &Response{"Gateway timeout\n", 504}&nbsp;&nbsp; &nbsp; }&nbsp; &nbsp; return}现在,不能同时写入 res。它将是超时或返回的值Get(url)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go