第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

第一次完成時(shí)如何安全地繞過(guò)其他 goroutine 的結(jié)果

第一次完成時(shí)如何安全地繞過(guò)其他 goroutine 的結(jié)果

Go
狐的傳說(shuō) 2021-11-22 10:45:50
我想向幾臺(tái)服務(wù)器詢問(wèn)數(shù)據(jù)(例如多個(gè)只讀副本)。在這項(xiàng)任務(wù)中最重要的是速度,因此應(yīng)該提供第一個(gè)結(jié)果,而其他所有結(jié)果都可以忽略。我對(duì)繞過(guò)這些數(shù)據(jù)的慣用方式有疑問(wèn)。當(dāng)它退出時(shí),有這個(gè)問(wèn)題的一切都沒(méi)有問(wèn)題(所有較慢的 goroutine 都沒(méi)有完成它們的工作,因?yàn)橹鬟M(jìn)程存在)。但是當(dāng)我們?nèi)∠詈笠恍械淖⑨專(zhuān)ㄊ褂?Sleep)時(shí),我們可以看到其他 goroutines 也在做他們的工作?,F(xiàn)在我正在通過(guò)通道推送數(shù)據(jù)有沒(méi)有辦法不推送它們?處理此類(lèi)問(wèn)題的好方法是什么?package mainimport (    "fmt"    "log"    "math/rand"    "time")type Result inttype Conn struct {    Id int}func (c *Conn) DoQuery(params string) Result {    log.Println("Querying start", params, c.Id)    time.Sleep(time.Duration(rand.Int31n(1000)) * time.Millisecond)    log.Println("Querying end", params, c.Id)    return Result(1000 + c.Id*c.Id)}func Query(conns []Conn, query string) Result {    ch := make(chan Result)    for _, conn := range conns {        go func(c Conn) {            ch <- c.DoQuery(query)        }(conn)    }    return <-ch}func main() {    conns := []Conn{Conn{1}, Conn{2}, Conn{3}, Conn{4}, Conn{5}}    result := Query(conns, "query!")    fmt.Println(result)    // time.Sleep(time.Minute)}
查看完整描述

1 回答

?
千萬(wàn)里不及你

TA貢獻(xiàn)1784條經(jīng)驗(yàn) 獲得超9個(gè)贊

我的建議是,使CH緩沖通道,每個(gè)查詢一個(gè)空間:ch := make(chan Result, len(conns))。這樣每個(gè)查詢都可以運(yùn)行完成,并且不會(huì)阻塞通道寫(xiě)入。


Query可以讀取一次并返回第一個(gè)結(jié)果。當(dāng)所有其他 goroutine 完成時(shí),通道最終將被垃圾回收,一切都會(huì)消失。使用無(wú)緩沖通道,您可以創(chuàng)建許多永遠(yuǎn)不會(huì)終止的 goroutine。


編輯:如果你想取消飛行中的請(qǐng)求,它會(huì)變得更加困難。某些操作和 API 提供取消功能,而其他操作和 API 則不提供。對(duì)于 http 請(qǐng)求,您可以Cancel在請(qǐng)求結(jié)構(gòu)上使用字段。只需提供一個(gè)您可以關(guān)閉以取消的頻道:


func (c *Conn) DoQuery(params string, cancel chan struct{}) Result {

    //error handling omitted. It is important to handle errors properly. 

    req, _ := http.NewRequest(...)

    req.Cancel = cancel

    resp, _ := http.DefaultClient.Do(req)

    //On Cancellation, the request will return an error of some kind.

    return readData(resp)

}

func Query(conns []Conn, query string) Result {

    ch := make(chan Result)

    cancel := make(chan struct{})

    for _, conn := range conns {

        go func(c Conn) {

            ch <- c.DoQuery(query,cancel)

        }(conn)

    }


    first := <-ch

    close(cancel)

    return first

}

如果有一個(gè)您不關(guān)心的大型讀取請(qǐng)求,這可能會(huì)有所幫助,但它實(shí)際上可能會(huì)或可能不會(huì)取消遠(yuǎn)程服務(wù)器上的請(qǐng)求。如果您的查詢不是 http,而是數(shù)據(jù)庫(kù)調(diào)用或其他什么,您將需要查看是否有類(lèi)似的取消機(jī)制可以使用。


查看完整回答
反對(duì) 回復(fù) 2021-11-22
  • 1 回答
  • 0 關(guān)注
  • 214 瀏覽
慕課專(zhuān)欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)