我的应用程序中运行了许多例程,并且我有另一个例程必须在同一时间段只处理一个请求,然后将结果发送回调用者。
这意味着其他例程应该等待,直到必要的(单操作)例程繁忙。
[goroutine 1] <-
-
-
-
[goroutine 2]<- - - - -> [Process some data in a single goroutine and send the result back to caller
-
-
-
[goroutine 3] <-
这是它应该看起来像的图表
我对Go非常非常陌生,我对如何正确实现它知之甚少。
是否有人可以为我提供一些工作示例,以便我可以在go playground上运行它?
这里有一个代码片段,它有几个工作程序和一个处理器程序。因为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 %dn", i)
response := <-responseChannel
fmt.Printf("** Received the response %dn", response)
// Do some work
time.Sleep(300 * time.Millisecond)
}
}
func runProcessor(processorChannel chan *WorkPackage) {
for workPackage := range processorChannel {
fmt.Printf("## Received %dn", workPackage.value)
// Do some processing work
time.Sleep(100 * time.Millisecond)
workPackage.responseChannel <- workPackage.value * 100
}
}
我将用一个将两个数字相加的例程来描述这种方法。
声明程序的请求和响应类型。在请求中包含一个响应值通道:
type request struct {
a, b int // add these two numbers
ch chan response
}
type response struct {
n int // the result of adding the numbers
}
启动一个接收请求、执行操作并向请求中的通道发送响应的例程:
func startAdder() chan request {
ch := make(chan request)
go func() {
for req := range ch {
req.ch <- response{req.a + req.b}
}
}()
return ch
}
要添加数字,向带有响应通道的例程发送请求。在响应通道上接收。返回响应值
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上运行。