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

时间:2019-01-24 23:26:57

标签: go goroutine

**编辑要更加简洁明了

我对Go相当陌生,对GoRoutines绝对陌生,但是我需要为正在构建的程序添加一定程度的并发性。

我打算与此同时使两个go func同时运行,并且从技术上来说,它们都是运行的。但是他们并没有像我期望的那样运行。

顶部go func应该每五秒钟运行一次,以查找新作业和打开设备以运行该作业。如果有新作业,它将检查打开的设备。假设有三个新作业和两个打开的设备,for _, device := range循环应运行两次,以将每个作业分配给一个设备。五秒钟后,循环将再次运行,并看到还有一个作业要运行,并检查这些设备是否已打开以运行该作业。 同时,我希望subSSH函数能够被连续调用。

实际上发生的事情是,设备循环每五秒钟运行一次,因此它只使用第一个设备并运行代码,然后等待五秒钟,然后对第二项工作,第三项工作执行相同的操作,永远不要使用第二个设备或运行两次该循环。

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

我尝试在其中添加等待组并为新作业的数量添加新的等待,但这导致设备循环根本无法执行。

我想我在这里缺少明显的东西,我们非常感谢您的协助! 谢谢!

1 个答案:

答案 0 :(得分:1)

您的代码处于正确的位置,但是变量的作用域错误。您也有一个嵌套的for循环,因此继续将其删除。

您会想要这样的东西:

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

应该可以解决问题。参见:https://play.golang.org/p/zj6jdoduCcp

如果要连续执行goroutine,则需要连续循环。

// only executes once and quits.
go func() { doTheThing() }()

// executes continuously after each execution exit.
go func() { for { doTheThing() } }()

// "background" function
go func() { doTheThingThatNeverExits() }()

goroutine被设计为后台进程(过度简化)。 goroutine只是一个易于使用的包装器,用于在调用函数时轻松并发。

编辑:错过了最后一位。