我有一个案例,我用第三方包读取excel文件,我需要goroutine进行一些逻辑读取,并在循环过程中将它们插入数据库,
这是我试过的
var wg sync.WaitGroup
var mapMutex sync.RWMutex
for _, sheet := range originFile.Sheets {
for _, row := range sheet.Rows {
item := map[string]interface{}{}
for cellIdx, cell := range row.Cells {
wg.Add(1)
cell := cell
cellIdx := cellIdx
go func() {
defer wg.Done()
index := fmt.Sprintf("%v", sheet.Rows[0].Cells[cellIdx])
logrus.Info(item[index]) // i got <nil> here
mapMutex.Lock()
item[index] = cell
mapMutex.Unlock()
}()
}
// i want `item` here to do something again for my function
logrus.Info(item) // i got map[] here (empty)
}
}
wg.Wait()
为什么我这么做是因为数据,多于>10.000,所以我需要使用它来读取并插入数据库(也有一些逻辑(
这里有人以前有这个问题吗?你是怎么解决的??
如果你需要一个go例程,我会重新考虑。如果没有,一切都会更容易。但是,如果你对goroutines有很强的需求和资源,你需要做两件事,但首先让我解释一下原因!
基本上,您最内部的for循环是在CPU和驱动器允许的情况下以最快的速度迭代row.Cells
,生成goroutine并迭代下一个,依此类推。item
是一个局部变量,仅在for循环的范围内已知。
所以你需要:
- 首先用make:
item := make(map[string]interface{})
准备地图 - 然后将其作为参数传递给goroutine函数,并需要其他值:
go func(i map[string]interface{}, c string, cIdx int) {
...
}(item, cell, cellIdx)
还有人评论道:即使在日志记录时从映射中读取,也需要一个互斥对象。