Go例程未执行

时间:2018-10-14 11:47:57

标签: go goroutine go-sqlite3

以下是给我问题的代码。我要实现的是并行创建那些表。创建所有表后,我要退出功能。

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 :(得分:3)

您尝试实现的通常模式是使用WaitGroup

我认为您面临的问题是i被每个goroutine捕获,并且不断被外循环递增。您的内部循环从i开始,由于外部循环一直在继续,因此每个goroutine从5开始。

尝试将迭代器作为参数传递给goroutine,以便每次获得一个新副本。

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();     
}

我不确定您要在这里实现什么,每个goroutine在它开始的那个表上方的所有表上执行db.Exec,因此第一个处理所有表,第二个处理所有表,但是第一个,依此类推。这是您想要的吗?