登录
首页 >  Golang >  Go问答

例程未运行

来源:stackoverflow

时间:2024-03-25 09:48:32 492浏览 收藏

本代码中,`someFunction` 函数旨在并行创建多个表。它使用 goroutine 来实现并行性,但遇到问题,导致 goroutine 无法完成表创建并退出函数。

问题内容

以下是给我带来问题的代码。我想要实现的是并行创建那么多表。创建所有表后,我想退出函数。

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 被终止。

但是如果顺序运行代码就没有问题

我的设计模式有什么错误以及如何纠正它。


解决方案


您想要实现的目标的通常模式使用 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 ,所以第一个处理所有表,第二个处理除第一个表之外的所有表一等等。这是你想要的吗?

到这里,我们也就讲完了《例程未运行》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>