限制运行的并发任务数

时间:2016-02-10 22:54:38

标签: go concurrency

所以我经常与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个并发任务不是问题吗?

1 个答案:

答案 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()
}