dongzhizhai4070 2019-01-24 23:26 采纳率: 0%
浏览 42
已采纳

多Go例程循环未按预期执行

**EDIT to be more concise and clear

I'm fairly new to Go and absolutely new to GoRoutines, but I need to add a level of concurrency to my program I'm building.

What I'm looking to do with this is have both go func running concurrently, and they are, technically. They aren't running how I would expect them too however.

The top go func should run every five seconds looking for a new job and an open device to run the job on. If there are new jobs it checks for open devices. Assuming there are three new jobs and two open devices the for _, device := range loop should run twice assigning each job to a device. Five seconds later the loop would run again and see there is one job left to be run, and check if those devices are open to run the job. Meanwhile I'd expect the subSSH function to be continuously called.

What's actually happening is that the device loop only runs once every five seconds, so it only takes the first device and runs the code, then it waits five seconds and does the same thing with the second job, then the third job, never utilizing the second device or running that loop twice.

go func() {
    for {
        duration := 5 * time.Second
        for x := range time.Tick(duration) {//this loop runs every five seconds
            newJobs := checkForNew(jobcoll)
            if len(newJobs) != 0 {
                openPool := checkPoolDeviceStatus(poolcoll)
                for _, device := range openDevices {
                    //for each open device this loop should run once

                }
            }
        }
    }
}()

go func() {
    subSSH(subChannel, jobcoll, poolcoll)
}()

I've attempted adding wait groups in and adding a new wait for the number of new jobs, but this caused the device loop to never execute at all.

I think I'm missing something obvious here, and any assitance is much appreciated! Thanks!

  • 写回答

1条回答 默认 最新

  • duandao3265 2019-01-25 04:03
    关注

    You're on the right path with the ticker, but you have the variables in the wrong scopes. You also have a nested for loop, so go ahead and remove that.

    You'll want something like this:

    go func() {
        ticker := time.NewTicker(5 * time.Second) // setup outside the loop.
        for t := range ticker.C { // every time 5 seconds passes, this channel will fire.
            newJobs := checkForNew(jobcoll)
            if len(newJobs) != 0 {
                openPool := checkPoolDeviceStatus(poolcoll)
                for _, device := range openDevices {
                    // the thing should occur.
                }
            }
        }
    }()
    

    That should do the trick. See: https://play.golang.org/p/zj6jdoduCcp

    If you want a continuously executing goroutine, you'd want a continuous loop.

    // only executes once and quits.
    go func() { doTheThing() }()
    
    // executes continuously after each execution exit.
    go func() { for { doTheThing() } }()
    
    // "background" function
    go func() { doTheThingThatNeverExits() }()
    

    A goroutine is designed to be a background process (oversimplication). A goroutine is just an ease-of-use wrapper for easy concurrency when calling functions.

    Edit: Missed the last bit.

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

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器