我正在关注https://blog.golang.org/pipelines文章,以实施几个阶段。
我需要其中一个阶段在事件传递到管道中的下一个阶段之前引入几秒的延迟。
我对下面代码的关注是它会在传递事件之前产生无限数量的go例程time.Sleep()。有更好的方法吗?
谢谢!
func fooStage(inChan <- chan *Bar) (<- chan *Bar) {
out := make(chan *Bar, 10000)
go func() {
defer close(out)
wg := sync.WaitGroup{}
for {
select {
case event, ok := <-inChan:
if !ok {
// inChan closed
break
}
wg.Add(1)
go func() {
time.Sleep(5 * time.Second)
out <- event
wg.Done()
}()
}
}
wg.Wait()
}()
return out
}
答案 0 :(得分:1)
您可以使用其他通道来限制循环能够创建的活动goroutine的数量。
const numRoutines = 10
func fooStage(inChan <-chan *Bar) <-chan *Bar {
out := make(chan *Bar, 10000)
routines := make(chan struct{}, numRoutines)
go func() {
defer close(out)
wg := sync.WaitGroup{}
for {
select {
case event, ok := <-inChan:
if !ok {
// inChan closed
break
}
wg.Add(1)
routines <- struct{}{}
go func() {
time.Sleep(5 * time.Second)
out <- event
wg.Done()
<-routines
}()
}
}
wg.Wait()
}()
return out
}
答案 1 :(得分:1)
您可以手动修复goroutines的数量 - 仅从您需要的数字开始。
func sleepStage(in <-chan *Bar) (out <-chan *Bar) {
out = make(<-chan *Bar)
wg := sync.WaitGroup
for i:=0; i < N; i++ { // Number of goroutines in parallel
wg.Add(1)
go func(){
defer wg.Done()
for e := range in {
time.Sleep(5*time.Seconds)
out <- e
}
}()
}
go func(){}
wg.Wait()
close(out)
}()
return out
}
答案 2 :(得分:0)
您可以使用std::string line;
while (getline(ss, line) && !line.empty()) {
size_t startOfNumbers = line.find_first_of("0123456789");
size_t endOfName = line.find_last_not_of(" ", startOfNumbers);
std::string name = line.substr(0, endOfName); // Extract name
std::stringstream nums(line.substr(startOfNumbers)); // Get rest of the line
int num1, num2;
nums >> num1 >> num2; // Read numbers
std::cout << name << " " << num1 << " " << num2 << std::endl;
}
:
time.Ticker
答案 3 :(得分:0)
这是您应该用于管道应用程序的内容。上下文允许更快地拆除。
负责管理您的 in
频道的必须在拆除期间关闭它。 始终关闭您的频道。
// Delay delays each `interface{}` coming in through `in` by `duration`.
// If the context is canceled, `in` will be flushed until it closes.
// Delay is very useful for throtteling back CPU usage in your pipelines.
func Delay(ctx context.Context, duration time.Duration, in <-chan interface{}) <-chan interface{} {
out := make(chan interface{})
go func() {
// Correct memory management
defer close(out)
// Keep reading from in until its closed
for i := range in {
// Take one element from in and pass it to out
out <- i
select {
// Wait duration before reading from in again
case <-time.After(duration):
// Don't wait if the context is canceled
case <-ctx.Done():
}
}
}()
return out
}
答案 4 :(得分:0)
我已经用我的 pipeline library 解决了这样的问题,就像这样:
import "github.com/nazar256/parapipe"
//...
pipeline := parapipe.NewPipeline(10).
Pipe(func(msg interface{}) interface{} {
//some code
}).
Pipe(func(msg interface{}) interface{} {
time.Sleep(3*time.Second)
return msg
}).
Pipe(func(msg interface{}) interface{} {
//some other code
})