代码之家  ›  专栏  ›  技术社区  ›  pr0p

Go例程未执行

  •  1
  • pr0p  · 技术社区  · 6 年前

    下面是给我带来问题的代码。我想要实现的是并行地创建这些表。创建完所有表之后,我想退出函数。

    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 回复  |  直到 6 年前
        1
  •  3
  •   Motti    6 年前

    你想要达到的通常模式 WaitGroup .

    我想你面临的问题是 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();     
    }
    

    db.Exec