我有一个函数a
:
func a(input *some_type) {
// do sth.
b(input)
}
多次调用此函数。
我希望函数b
无限期地等待来自函数a
的输入,并在收集了n个输入时执行操作。
func b(input *some_type) {
// wait until received n inputs then do sth. with all inputs
}
我该怎么做呢?我的第一个想法是使用sync.WaitGroup
与a
和b
之间的频道。
答案 0 :(得分:2)
这是一个常见的生产者 - 消费者问题。使用通道等待来自另一个例程的输入。这样的事情有帮助吗?
在这个特定示例中,您必须在收到输入后再次调用go b(c)
,但您可以轻松地在无限b
循环中包装for
。或者无论发生什么事情。
请注意,在此示例中,使用了无缓冲的channel
,这会强制两个例程同时满足以“切换”*Thing
。如果您希望生产者(a
的进程)不必等待,您可以使用缓冲通道,其创建如下:
c := make(chan(*Thing, n))
其中n
是频道可以存储的项目数。这允许几个人被生产者排队。
https://play.golang.org/p/X14_QsSSU4
package main
import (
"fmt"
"time"
)
type Thing struct {
N int
}
func a(t *Thing, c chan (*Thing)) {
// stuff happens. whee
c <- t
}
func b(c chan (*Thing)) {
things := []*Thing{}
for i := 0; i < 10; i++ {
t := <-c
things = append(things, t)
fmt.Printf("I have %d things\n", i+1)
}
fmt.Println("I now have 10 things! Let's roll!")
// do stuff with your ten things
}
func main() {
fmt.Println("Hello, playground")
c := make(chan (*Thing))
go b(c)
// this would probably be done producer-consumer like in a go-routine
for i := 0; i < 10; i++ {
a(&Thing{i}, c)
time.Sleep(time.Second)
}
time.Sleep(time.Second)
fmt.Println("Program finished")
}