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

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

與 Channel 的雙向通信

與 Channel 的雙向通信

Go
忽然笑 2022-06-01 17:25:14
在下面的代碼中:package mainimport (    "fmt"    "io/ioutil"    "net/http")func getPage(url string) (int, error) {    resp, err := http.Get(url)    if err != nil {        return 0, err    }    defer resp.Body.Close()    body, err := ioutil.ReadAll(resp.Body)    if err != nil {        return 0, err    }    return len(body), nil}func getter(urlChan chan string, size chan int) {    url := <-urlChan    length, err := getPage(url)    if err == nil {        size <- length        urlChan <- url    }}func main() {    urls := []string{"http://www.google.com/", "http://www.yahoo.com",        "http://www.bing.com", "http://bbc.co.uk"}    sizeChan := make(chan int)    urlChan := make(chan string)    for _, url := range urls {        urlChan <- url        go getter(urlChan, sizeChan)    }    for i := 0; i < len(urls); i++ {        fmt.Printf("%s has length %d\n", <-urlChan, <-sizeChan)    }}我urlChan用作雙向,以了解計(jì)算urlChan給定 size( sizeChan) 的 url()。對(duì)于getter()go-routine,在對(duì) 進(jìn)行第一個(gè)字符串參數(shù)url后 urlChan,下面的輸出顯示了掛起情況:$ go install github.com/shamhub/cs61a$ $ $ bin/cs61a 1)如何在通道上進(jìn)行雙向通信?2) 如何分析給定進(jìn)程的 go-routines 狀態(tài)?
查看完整描述

2 回答

?
千萬里不及你

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

正如其他人已經(jīng)指出的那樣,您可以更簡(jiǎn)單地解決這個(gè)問題:


type sized struct {

    url    string

    length int

    err    error

}


func sizer(url string, result chan<- sized, wg *sync.WaitGroup) {

    defer wg.Done()

    length, err := getPage(url)

    result <- sized{url, length, err}

}


func main() {

    urls := []string{"http://www.google.com/", "http://www.yahoo.com",

        "http://www.bing.com", "http://bbc.co.uk"}


    ch := make(chan sized)

    var wg sync.WaitGroup

    for _, url := range urls {

        wg.Add(1)

        go sizer(url, ch, &wg)

    }

    go func() {

        wg.Wait()

        close(ch)

    }()


    for result := range ch {

        if result.err != nil {

            fmt.Printf("%s: %s\n", result.url, result.err)

        } else {

            fmt.Printf("%s: length = %d\n", result.url, result.length)

        }

    }

}

操場(chǎng)上的完整示例,雖然它不能撥出,所以在那里不是很有用。


如何在通道上進(jìn)行雙向通信?


你不能。


嗯,這并不完全正確。讓我們說:你不應(yīng)該.


假設(shè)我們有一個(gè)頻道:


var ch chan T

對(duì)于某些類型 T。


頻道本身是天生的......好吧,我認(rèn)為非定向是正確的詞:


任何人都可以將任何類型 T 的值放入通道中ch <- val

任何人都可以從通道中取出任何類型 T 的值var <- ch

這顯然不是單向的,但我認(rèn)為稱其為雙向是一種誤導(dǎo):它有一個(gè)“放入”一側(cè)和一個(gè)“取出”一側(cè),兩者都集中在一個(gè)通道實(shí)例中,但該通道與任何通道都沒有關(guān)聯(lián)特定用戶。您可以在任一方向上將通道值復(fù)制到有向?qū)嵗ㄕ?qǐng)參閱Go 中單向通道的意義何在?),但兩者實(shí)際上都只是對(duì)底層非定向通道對(duì)象的引用。1 然后,您可以將原始通道或其單向化副本傳遞給任何用戶,或?qū)⑵渲腥魏我粋€(gè)視為任何人都可以使用的“全局”(寬范圍)變量。


現(xiàn)在讓我們添加兩個(gè)實(shí)體,我們將其稱為 X 和 Y。如果 channelch是buffered,則 X 和 Y 中的一個(gè)或兩個(gè)可以放入項(xiàng)目,然后 A 和 B 中的一個(gè)或兩個(gè)可以取出項(xiàng)目。項(xiàng)目將按照進(jìn)入的順序出現(xiàn),序列化訪問;如果通道已滿,則嘗試將項(xiàng)目放入將被阻止;但項(xiàng)目不會(huì)專門從X轉(zhuǎn)移到Y(jié)。特別是:


// Y: paused or stopped


// do this in X when ch is initially empty:

ch <- T{}

v := <-ch

在這里,X 將一個(gè)零值T放入通道,然后將其取出。這不是定向的。X 取回了自己的數(shù)據(jù)。


如果通道不是空的,也不是滿的,X 或 Y 可以向它添加一些東西(作為一個(gè)隊(duì)列),然后從隊(duì)列的前面取出一些東西。但這只是將通道用作隊(duì)列。(參見Is it possible to use Go's buffered channel as a thread-safe queue?)


如果此隊(duì)列具有它肯定缺少的某些功能,您可以使用單個(gè)隊(duì)列進(jìn)行雙向通信(請(qǐng)參閱Is two way comm possible using a single message queue in C)。但它沒有它們。如果真的需要雙向通信,答案很明顯:使用兩個(gè)隊(duì)列。指定一個(gè)隊(duì)列(一個(gè)通道)作為 X-sends-to-Y 通道,另一個(gè)作為 Y-sends-to-X 通道。


查看完整回答
反對(duì) 回復(fù) 2022-06-01
?
POPMUISE

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

你必須閱讀并練習(xí) go tour,我相信下面代碼中使用的每個(gè)細(xì)節(jié)都會(huì)在那里解釋,但是,這是一個(gè)解決方案


package main


import (

    "fmt"

    "io/ioutil"

    "log"

    "net/http"

    "sync"

)


func getPage(url string) (int, error) {

    resp, err := http.Get(url)

    if err != nil {

        return 0, err

    }


    defer resp.Body.Close()


    body, err := ioutil.ReadAll(resp.Body)

    if err != nil {

        return 0, err

    }


    return len(body), nil

}


type result struct {

    url string

    len int

    err error

}


func main() {

    urls := []string{"http://www.google.com/", "http://www.yahoo.com",

        "http://www.bing.com", "http://bbc.co.uk"}


    resChan := make(chan result)

    var wg sync.WaitGroup

    for _, url := range urls {

        wg.Add(1)

        go func(url string) {

            defer wg.Done()

            l, err := getPage(url)

            resChan <- result{url: url, len: l, err: err}

        }(url)

    }


    go func() {

        wg.Wait()

        close(resChan)

    }()


    for r := range resChan {

        if r.err != nil {

            log.Printf("failed to fetch %q: %v\n", r.url, r.err)

            continue

        }

        fmt.Printf("%s has length %d\n", r.url, r.len)

    }

}

這并不理想,因?yàn)樗粫?huì)限制并發(fā)傳出請(qǐng)求的數(shù)量。


關(guān)于,2) How to profile the status of go-routines for a given process?


請(qǐng)參閱 pprof 工具。有一個(gè)文檔https://golang.org/doc/diagnostics.html



查看完整回答
反對(duì) 回復(fù) 2022-06-01
  • 2 回答
  • 0 關(guān)注
  • 114 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號(hào)

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