Перейти подпрограммы не выполняются
Ниже приведен код, который вызывает у меня проблему. Чего я хочу добиться, так это создавать эти параллельные таблицы. После того, как все таблицы созданы, я хочу выйти из функций.
func someFunction(){
....
gos := 5
proc := make(chan bool, gos)
allDone := make(chan bool)
for i:=0; i<gos; i++ {
go func() {
for j:=i; j<len(tables); j+=gos {
r, err := db.Exec(tables[j])
fmt.Println(r)
if err != nil {
methods.CheckErr(err, err.Error())
}
}
proc <- true
}()
}
go func() {
for i:=0; i<gos; i++{
<-proc
}
allDone <- true
}()
for {
select {
case <-allDone:
return
}
}
}
Я создаю два канала 1, чтобы отслеживать количество созданных таблиц (proc) и другие (allDone), чтобы увидеть, все ли сделано.
Когда я запускаю этот код, тогда процедура go для создания таблицы начинает выполнение, но до ее завершения некоторая функция завершается.
Однако нет проблем, если запустить код последовательно
В чем заключается ошибка в моем шаблоне дизайна, а также как я могу ее исправить.
1 ответ
Обычный образец того, что вы пытаетесь достичь, использует WaitGroup
,
Я думаю, что проблема, с которой вы сталкиваетесь, заключается в том, что i
захватывается каждой программой и продолжает увеличиваться внешним циклом. Ваш внутренний цикл начинается с i
и так как внешний цикл продолжался, каждая процедура начинается с 5.
Попробуйте передать итератор в качестве параметра в программу, чтобы вы каждый раз получали новую копию.
func someFunction(){
....
gos := 5
var wg sync.WaitGroup
wg.Add(gos)
for i:=0; i< gos; i++ {
go func(n int) {
defer wg.Done()
for j:=n; j<len(tables); j+=gos {
r, err := db.Exec(tables[j])
fmt.Println(r)
if err != nil {
methods.CheckErr(err, err.Error())
}
}
}(i)
}
wg.Wait();
}
Я не уверен, что вы пытаетесь достичь здесь, каждая процедура делает db.Exec
на всех таблицах выше той, с которой он начинался, поэтому первая обрабатывает все таблицы, вторая - все, кроме первой и так далее. Это то, что вы хотели?