dougu2036 2018-10-14 11:47
浏览 51
已采纳

Go例程未执行

The following is the code that is giving me problem. What i want to achieve is to create those many tables in parallel. After all the tables are created I want to exit the functions.

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
        }
    }   
}

I'm creating two channels 1 to keep track of number of tables created (proc) and other (allDone) to see if all are done.

When i run this code then the go routine to create table starts execution but before it completes someFunction gets terminated.

However there is no problem if run the code sequentially

What is the mistake in my design pattern and also how do i correct it.

  • 写回答

1条回答 默认 最新

  • douchuo9476 2018-10-14 12:05
    关注

    The usual pattern for what you're trying to achieve uses WaitGroup.

    I think the problem you're facing is that i is captured by each goroutine and it keeps getting incremented by the outer loop. Your inner loop starts at i and since the outer loop has continued, each goroutine starts at 5.

    Try passing the iterator as parameter to the goroutine so that you get a new copy each time.

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

    I'm not sure what you're trying to achieve here, each goroutine does db.Exec on all the tables above the one it started with so the first one treats all the tables, the second one treats all but the first one and so on. Is this what you intended?

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥170 如图所示配置eNSP
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥15 键盘指令混乱情况下的启动盘系统重装