【发布时间】:2019-01-02 09:17:21
【问题描述】:
我正在编写一个程序来处理文本文件中的数百万行,500k 需要 5 秒来验证文件,我想加快速度。
我想循环遍历这些项目并异步处理其中的 x 个,然后等待响应以查看是否应该继续。
我写了一些虚拟代码,我不确定我写的内容是否有意义,只是看起来相当复杂,有没有更简单更优雅的方法。
package main
import (
"fmt"
"sync"
"time"
)
func main() {
// Need an object to loop over
// need a loop to read the response
items := 100000
concurrency := 20
sem := make(chan bool, concurrency)
returnChan := make(chan error)
finChan := make(chan bool)
var wg sync.WaitGroup
go func() {
for x := 0; x < items; x++ {
// loop over all items
// only do maxitems at a time
wg.Add(1)
sem <- true
go delayFunc(x, sem, returnChan, &wg)
}
wg.Wait()
finChan <- true
}()
var err error
finished := false
for {
select {
case err = <-returnChan:
if err != nil {
break
}
case _ = <-finChan:
finished = true
break
default:
continue
}
if err != nil || finished == true {
break
}
}
fmt.Println(err)
}
func delayFunc(x int, sem chan bool, returnChan chan error, wg *sync.WaitGroup) {
//fmt.Printf("PROCESSING (%v)\n", x)
time.Sleep(10 * time.Millisecond)
<-sem // release the lock
wg.Done()
if x == 95000 {
returnChan <- fmt.Errorf("Something not right")
} else {
returnChan <- nil
}
}
【问题讨论】:
-
在 WaitGroup 初始化之后,不要一一添加到
wg,而是执行wg.Add(items)之类的操作。这不是您要问的,但这可能会造成难以捕捉的错误,因为“items+1”不同的 go 例程正在访问 wg 变量。 -
谢谢您,我不确定我的示例是否完全说明了我在做什么,我将读取相当大的文件,因此将逐行缓冲
标签: go concurrency channel