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

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

使用通道進(jìn)行請求-響應(yīng)通信的慣用方式

使用通道進(jìn)行請求-響應(yīng)通信的慣用方式

Go
牛魔王的故事 2021-09-09 14:06:33
也許我只是沒有正確閱讀規(guī)范,或者我的心態(tài)仍然堅持使用舊的同步方法,但是在 Go中發(fā)送一種類型作為接收其他類型作為響應(yīng)的正確方法是什么?我想出的一種方法是package mainimport "fmt"type request struct {    out chan string    argument int}var input = make(chan *request)var cache = map[int]string{}func processor() {    for {        select {            case in := <- input:                if result, exists := cache[in.argument]; exists {                    in.out <- result                }                result := fmt.Sprintf("%d", in.argument)                cache[in.argument] = result                in.out <- result        }    }}func main() {    go processor()    responseCh := make(chan string)    input <- &request{        responseCh,        1,    }    result := <- responseCh    fmt.Println(result)}該緩存對于此示例并不是真正必需的,否則會導(dǎo)致數(shù)據(jù)競爭。這是我應(yīng)該做的嗎?
查看完整描述

1 回答

?
慕萊塢森

TA貢獻(xiàn)1810條經(jīng)驗 獲得超4個贊

有很多可能性,取決于您的問題的最佳方法。當(dāng)您從頻道收到某些信息時,沒有什么比默認(rèn)的響應(yīng)方式更合適的了——您需要自己構(gòu)建流程(并且您在問題中的示例中確實做到了)。為每個請求發(fā)送響應(yīng)通道為您提供了極大的靈活性,因為您可以選擇將響應(yīng)路由到何處,但通常沒有必要。


以下是一些其他示例:


1. 同頻道發(fā)送和接收


您可以使用無緩沖通道來發(fā)送和接收響應(yīng)。這很好地說明了無緩沖通道實際上是您程序中的同步點。限制當(dāng)然是我們需要發(fā)送與請求和響應(yīng)完全相同的類型:


package main


import (

    "fmt"

)


func pow2() (c chan int) {

    c = make(chan int)

    go func() {

        for x := range c {

            c <- x*x

        }

    }()

    return c

}


func main() {

    c := pow2()

    c <- 2

    fmt.Println(<-c) // = 4

    c <- 4

    fmt.Println(<-c) // = 8

}

2. 發(fā)送到一個頻道,從另一個頻道接收


您可以將輸入和輸出通道分開。如果您愿意,您可以使用緩沖版本。這可以用作請求/響應(yīng)場景,并允許您擁有一個負(fù)責(zé)發(fā)送請求的路由,另一個用于處理它們,另一個用于接收響應(yīng)。例子:


package main


import (

    "fmt"

)


func pow2() (in chan int, out chan int) {

    in = make(chan int)

    out = make(chan int)

    go func() {

        for x := range in {

            out <- x*x

        }       

    }()

    return

}


func main() {

    in, out := pow2()

    go func() {

        in <- 2

        in <- 4

    }()

    fmt.Println(<-out) // = 4

    fmt.Println(<-out) // = 8

}

3. 每次請求都發(fā)送響應(yīng)通道


這就是您在問題中提出的內(nèi)容。使您可以靈活地指定響應(yīng)路由。如果您希望響應(yīng)命中特定的處理例程,這很有用,例如,您有許多客戶端有一些任務(wù)要做,并且您希望響應(yīng)由同一個客戶端接收。


package main


import (

    "fmt"

    "sync"

)


type Task struct {

    x int

    c chan int

}


func pow2(in chan Task) {

    for t := range in {

        t.c <- t.x*t.x

    }       

}


func main() {

    var wg sync.WaitGroup   

    in := make(chan Task)


    // Two processors

    go pow2(in)

    go pow2(in)


    // Five clients with some tasks

    for n := 1; n < 5; n++ {

        wg.Add(1)

        go func(x int) {

            defer wg.Done()

            c := make(chan int)

            in <- Task{x, c}

            fmt.Printf("%d**2 = %d\n", x, <-c)

        }(n)

    }


    wg.Wait()

}

值得一提的是,這種場景不需要使用每個任務(wù)的返回通道來實現(xiàn)。如果結(jié)果具有某種客戶端上下文(例如客戶端 ID),則單個多路復(fù)用器可能會接收所有響應(yīng),然后根據(jù)上下文處理它們。


有時讓通道來實現(xiàn)簡單的請求-響應(yīng)模式是沒有意義的。在設(shè)計 Go 程序時,我發(fā)現(xiàn)自己試圖向系統(tǒng)中注入太多通道(只是因為我認(rèn)為它們真的很棒)。舊的好函數(shù)調(diào)用有時就是我們所需要的:


package main


import (

    "fmt"

)


func pow2(x int) int {

    return x*x

}


func main() {

    fmt.Println(pow2(2))

    fmt.Println(pow2(4))

}

(如果有人遇到類似的問題,因為在你的榜樣,這可能是一個很好的解決方案。附和你的問題下收到的意見,為保護(hù)單個結(jié)構(gòu),諸如高速緩存,它可能是最好創(chuàng)建一個結(jié)構(gòu)和揭露一些方法,這將保護(hù)與互斥鎖的并發(fā)使用。)


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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