为了账号安全,请及时绑定邮箱和手机立即绑定

Goroutines - 将关键数据发送到单个 goroutine 并等待结果

Goroutines - 将关键数据发送到单个 goroutine 并等待结果

Go
慕无忌1623718 2023-01-03 15:56:27
我的应用程序中运行着许多 goroutine,并且我有另一个 goroutine 必须在同一时间段内只处理一个请求,然后将结果发送回调用方。这意味着其他 goroutine 应该等到必要的(单操作)goroutine 忙。[goroutine 1] <-                  -                    -                      - [goroutine 2]<- - - -  -> [Process some data in a single goroutine and send the result back to caller                      -                    -                  - [goroutine 3] <-这是它应该是什么样子的图表我对 Go 非常陌生,而且我对如何正确实施它知之甚少。有人可以为我提供一些工作示例,以便我可以在 go playground 上运行它吗?
查看完整描述

2 回答

?
元芳怎么了

TA贡献1798条经验 获得超7个赞

这里有一个代码片段,其中包含一些 worker-goroutine 和一个 processor-goroutine。只有一个 worker-goroutine 可以向处理器发送一些东西,因为processorChannel它只允许一个条目。处理器完成后,他将响应发回给从中获得工作的工人。


package main


import (

    "fmt"

    "time"

)


type WorkPackage struct {

    value           int

    responseChannel chan int

}


func main() {

    processorChannel := make(chan *WorkPackage)


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

        go runWorker(processorChannel)

    }


    go runProcessor(processorChannel)


    // Do some clever waiting here like with wait groups

    time.Sleep(5 * time.Second)

}


func runWorker(processorChannel chan *WorkPackage) {

    responseChannel := make(chan int)


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

        processorChannel <- &WorkPackage{

            value:           i,

            responseChannel: responseChannel,

        }

        fmt.Printf("** Sent %d\n", i)


        response := <-responseChannel

        fmt.Printf("** Received the response %d\n", response)


        // Do some work

        time.Sleep(300 * time.Millisecond)

    }

}


func runProcessor(processorChannel chan *WorkPackage) {

    for workPackage := range processorChannel {

        fmt.Printf("## Received %d\n", workPackage.value)


        // Do some processing work

        time.Sleep(100 * time.Millisecond)

        

        workPackage.responseChannel <- workPackage.value * 100

    }

}


查看完整回答
反对 回复 2023-01-03
?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

我将使用添加两个数字的 goroutine 来描述该方法。


声明 goroutine 的请求和响应类型。在请求中包含一个响应值通道:


type request struct {

    a, b  int          // add these two numbers

    ch chan response

}


type response struct {

    n int              // the result of adding the numbers

}

启动接收请求的 goroutine,执行操作并将响应发送到请求中的通道:


func startAdder() chan request {

    ch := make(chan request)

    go func() {

        for req := range ch {

            req.ch <- response{req.a + req.b}

        }

    }()

    return ch

}

要添加数字,请使用响应通道向 goroutine 发送请求。在响应通道上接收。返回响应值。


func add(ch chan request, a, b int) int {

    req := request{ch: make(chan response), a: a, b: b}

    ch <- req

    return (<-req.ch).n

}

像这样使用它:


ch := startAdder()

fmt.Println(add(ch, 1, 2))

在 GoLang PlayGround 上运行它



查看完整回答
反对 回复 2023-01-03
  • 2 回答
  • 0 关注
  • 71 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信