Перейти подпрограммы не выполняются - PullRequest
0 голосов
/ 14 октября 2018

Ниже приведен код, который вызывает у меня проблему.Чего я хочу добиться, так это создавать эти таблицы параллельно.После того, как все таблицы созданы, я хочу выйти из функций.

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 для создания таблицы начинает выполнение, но до ее завершения функция someFunction завершается.

Однако при последовательном запуске кода

проблем не возникает. В чем заключается ошибкамой шаблон дизайна, а также как мне его исправить.

1 Ответ

0 голосов
/ 14 октября 2018

Обычный образец того, чего вы пытаетесь достичь, использует 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 на всех таблицах выше той, с которой она началась, поэтому первая обрабатывает все таблицы, вторая обрабатывает всено первый и тд.Это то, что вы намеревались?

...