所以我经常与go
讨论这个问题。我们说我有一个包含100,000行文本的文本文件。现在我想将所有这些行保存到数据库中。所以我会做这样的事情:
file, _ := iotuil.ReadFile("file.txt")
fileLines := strings.Split(string(file), "\n")
现在我将循环遍历文件中的所有行:
for _, l := range fileLines{
saveToDB(l)
}
现在我想同时运行这个saveToDB
func:
var wg sync.WaitGroup
for _, l := range fileLines{
wg.Add(1)
go saveToDB(l, &wg)
}
wg.Wait()
我不知道这是否是一个问题但是会运行100,000个并发功能。有没有办法说嘿运行100个并发函数等待所有那些完成再运行100多个。
for i, _ := range fileLine {
for t = 0; t < 100; t++{
wg.Add(1)
go saveToDB(fileLine[i], &wg)
}
wg.Wait()
}
我是否需要做类似的事情或者有更清洁的方法来解决这个问题?或者我运行100,000个并发任务不是问题吗?
答案 0 :(得分:4)
我认为最好的方法是保留一组工作人员goroutine,在渠道中为他们调度工作,然后关闭频道以便他们退出。
类似的东西:
// create a channel for work "tasks"
ch := make(chan string)
wg := sync.WaitGroup{}
// start the workers
for t = 0; t < 100; t++{
wg.Add(1)
go saveToDB(ch, &wg)
}
// push the lines to the queue channel for processing
for _, line := range fileline {
ch <- line
}
// this will cause the workers to stop and exit their receive loop
close(ch)
// make sure they all exit
wg.Wait()
然后saveFunction看起来像这样:
func saveToDB(ch chan string, wg *sync.WaitGroup) {
// cnosume a line
for line := range ch {
// do work
actuallySaveToDB(line)
}
// we've exited the loop when the dispatcher closed the channel,
// so now we can just signal the workGroup we're done
wg.Done()
}