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

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在這個特定示例中,我應(yīng)該在哪里關(guān)閉頻道?

在這個特定示例中,我應(yīng)該在哪里關(guān)閉頻道?

Go
慕標琳琳 2022-06-06 15:34:30
我只是在寫一個簡單的 Go 管道,目標是獲取 url 和打印狀態(tài)。在 fetchUrl 上,我需要關(guān)閉通道來通知 main,不會有數(shù)據(jù)傳入,所以釋放 main go 例程。但是我不能在循環(huán)后真正關(guān)閉 fetchurl 函數(shù)上的頻道,因為它會為時過早。我不想在應(yīng)用程序中添加等待組,因為目前我的整個目標是了解渠道。在 fetchurl 函數(shù)中,調(diào)用兩個通道只是為了確保一次只有 2 個作業(yè)。package mainimport (    "fmt"    "net/http"    "os")func gen(val []string) <-chan string {    out := make(chan string, len(val))    for _, val := range val {        out <- val    }    close(out)    return out}func fetchUrl(in <-chan string) <-chan string {    out := make(chan string)    two := make(chan struct{}, 2)    fmt.Println("blocked")    for url := range in {        two <- struct{}{}        go fetchWorker(url, two, out)    }    return out}func fetchWorker(url string, two chan struct{}, out chan string) {    res, err := http.Get("https://" + url)    if err != nil {        panic(err)    }    <-two    out <- fmt.Sprintf("[%d] %s\n", res.StatusCode, url)}func main() {    for val := range fetchUrl(gen(os.Args[1:])) {        fmt.Println(val)    }}
查看完整描述

1 回答

?
慕工程0101907

TA貢獻1887條經(jīng)驗 獲得超5個贊

out在將每個結(jié)果寫入通道后,您需要關(guān)閉通道。最簡單的方法是當所有的工作 goroutine 都退出時,而最簡單的方法是使用sync.WaitGroup. (在 Go 中,通道和 goroutine 是非常密切相關(guān)的概念,因此 goroutine 管理是使用通道的一部分。)


在現(xiàn)有代碼中,您可以將其綁定到您的fetchUrl函數(shù)中:


var wg sync.WaitGroup

for url := range in {

    two <- struct{}{}

    wg.Add(1)

    go func() {

        defer wg.Done()

        fetchWorker(url, two, out)

    }()

}

wg.Wait()

close(out)

編寫代碼時遇到的另一個結(jié)構(gòu)性問題是,兩者都gen創(chuàng)建fetchUrl通道,運行所有應(yīng)該寫入通道的代碼,并僅在這些編寫者完成后返回通道;由于在函數(shù)返回之前無法從通道中讀取任何內(nèi)容,這將導(dǎo)致死鎖。您可以通過在頂層創(chuàng)建所有通道并將它們傳遞給生成器函數(shù)來解決此問題。


如果您想要兩個工作人員從同一個 URL 隊列中讀取,標準模式是啟動兩個從同一個通道讀取和寫入的 goroutine。例如,您可以重寫fetchWorker為


func fetchWorker(urls <-chan string, out chan<- string) {

    for url := range urls {

        res, err := http.Get("https://" + url)

        if err != nil {

            panic(err)

        }

        out <- fmt.Sprintf("[%d] %s\n", res.StatusCode, url)

    }

}

在頂層,創(chuàng)建通道、創(chuàng)建工人、提供輸入并使用輸出。


func main() {

    urls := make(chan string)

    out := make(chan string)


    // Launch a goroutine to feed data into urls, then

    // close(urls), then stop

    go gen(os.Args[1:], urls)


    // Launch worker goroutines

    workerCount := 2

    var wg sync.WaitGroup

    for i := 0; i < workerCount; i++ {

        wg.Add(1)

        go func() {

            defer wg.Done()

            fetchWorker(urls, out)

        }()

    }


    // Launch a dedicated goroutine to close the channel

    go func() {

        wg.Wait()

        close(out)

    }()


    // Read the results

    for result := range(out) {

        fmt.Println(result)

    }

}


查看完整回答
反對 回復(fù) 2022-06-06
  • 1 回答
  • 0 關(guān)注
  • 106 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

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